/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-02-17
*/
package com.rzico.order.service;

import com.alibaba.fastjson.JSON;
import com.rzico.account.entity.Foundation;
import com.rzico.base.CommResult;
import com.rzico.basics.entity.Card;
import com.rzico.account.entity.Payment;
import com.rzico.account.entity.Receivable;
import com.rzico.account.entity.Refunds;
import com.rzico.account.enumx.OrderTypeEnum;
import com.rzico.account.model.Attach;
import com.rzico.account.service.*;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.basics.entity.*;
import com.rzico.basics.mapper.GoodsMapper;
import com.rzico.basics.mapper.MemberMapper;
import com.rzico.basics.service.*;
import com.rzico.core.entity.SysEmployee;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysMenu;
import com.rzico.core.entity.SysUser;
import com.rzico.core.service.SysMchService;
import com.rzico.core.service.SysUserService;
import com.rzico.exception.CustomException;
import com.rzico.basics.model.CouponCodeVo;
import com.rzico.basics.service.CouponCodeService;
import com.rzico.basics.service.CouponService;
import com.rzico.basics.service.PromotionService;
import com.rzico.order.entity.*;
import com.rzico.order.enumx.*;
import com.rzico.order.mapper.OrderMapper;
import com.rzico.order.mapper.VirtualStockMapper;
import com.rzico.order.model.OrderPaymentVo;
import com.rzico.order.print.PrinterUtil;
import com.rzico.util.RedisHandler;
import com.rzico.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <pre>
 * 销售单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
@Slf4j
public class OrderService extends BaseServiceImpl<Order, String> {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    protected GoodsMapper goodsMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private ProductService productService;

    @Autowired
    private BomItemService bomItemService;

    @Autowired
    private PointService pointService;

    @Autowired
    private MatchPointService matchPointService;

    @Autowired
    private DepositService depositService;

    @Autowired @Lazy
    private ShopService shopService;

    @Autowired @Lazy
    private AskforService askforService;

    @Autowired @Lazy
    private ShippingService shippingService;

    @Autowired @Lazy
    private ShippingItemService shippingItemService;

    @Autowired @Lazy
    private ProductPriceService productPriceService;

    @Autowired
    private DistributionService distributionService;

    @Autowired
    private DistributionItemService distributionItemService;

    @Autowired
    private ReceivableService receivableService;

    @Autowired
    private ReceiverService receiverService;

    @Autowired
    private CouponCodeService couponCodeService;

    @Autowired
    private CouponCodeOrderService couponCodeOrderService;

    @Autowired
    private CouponService couponService;

    @Autowired
    private MemberService memberService;

    @Autowired @Lazy
    private GiftCardService giftCardService;

    @Autowired @Lazy
    private GroupOrderService groupOrderService;

    @Autowired @Lazy
    private BargainBuyService bargainBuyService;

    @Autowired @Lazy
    private BargainPeriodService bargainPeriodService;

    @Autowired @Lazy
    private MsgService msgService;

    @Autowired @Lazy
    private VipService vipService;

    @Autowired
    private SysMchService sysMchService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired @Lazy
    private WarehouseService warehouseService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private CardService cardService;

    @Autowired @Lazy
    private VirtualProductService virtualProductService;

    @Autowired @Lazy
    private GroupBuyService groupBuyService;

    @Autowired @Lazy
    private VirtualStockService virtualStockService;

    @Autowired
    private OrderLogService orderLogService;

    @Autowired
    private RefundsService refundsService;

    @Autowired
    private FreightService freightService;

    @Autowired
    private FoundationService foundationService;

    @Autowired @Lazy
    private BomService bomService;

    @Autowired
    private PaymentService paymentService;

    @Autowired @Lazy
    private PromotionService promotionService;

    @Autowired @Lazy
    private ReturnService returnService;

    @Autowired @Lazy
    private OrderPromotionService orderPromotionService;

    @Autowired
    private RedisHandler redisHandler;

    @Override
    public BaseMapper<Order, String> getMapper() {
        return orderMapper;
    }

    //付款成功回调
    @Transactional(rollbackFor = Exception.class)
    public void paymentHandle(Long id) {

        while (!redisHandler.lock("order-payment-".concat(String.valueOf(id)),String.valueOf(id))) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        try {

            Order order = selectByPrimaryKey(id);
            if (order==null) {
                return;
            }

            if (order.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_CANCLE .getId())) {
                return;
            }

            if (order.getPaymentStatus().equals(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId())) {
                return;
            }

            //只用于第三方支付或钱包余额支付,付清剩余所有款项
            order.setAmountPaid(order.getAmountPayable());
            order.setPaymentStatus(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId());
            order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_CONFIRM.getId());
            orderMapper.updateByPrimaryKeySelective(order);

            OrderLog orderLog = new OrderLog();
            orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_PAYEMNT.getId());
            orderLog.setContent("订单已付款");
            orderLog.setCreateDate(new Date());
            orderLog.setOrderId(order.getId());
            orderLogService.insertUseGeneratedKeys(orderLog);

            order.setItemList(orderItemService.getItemList(id));

            confirm(id, null);

            try {
                Member member = memberService.selectByPrimaryKey(order.getMemberId());

                Map<String, Object> content = new HashMap<>();
                content.put("title", "您已成功下单");
                content.put("itemList", order.getItemList());
                content.put("sn", order.getSn());
                content.put("id", order.getId());
                msgService.sendNotity(member, "msg-order", "商家会尽快安排发货，请耐心等待", JSON.toJSONString(content),null);

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                DecimalFormat df = new DecimalFormat("0.00");
                SysUser sysUser = sysUserService.findById(member.getUserId());
                if (sysUser.getWxmId() != null) {
                    msgService.sendMiniOrderMsg(sysUser, sdf.format(new Date()), "您已成功下单", order.getTitle(), order.getSn(), df.format(order.getAmountPayable()), "点击查看订单详情");
                }
                if (sysUser.getWxId() != null) {
                    msgService.sendMPOrderMsg(sysUser, sdf.format(new Date()), "您已成功下单", order.getTitle(), order.getSn(), df.format(order.getAmountPayable()), "点击查看订单详情");
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }

        } finally {
            redisHandler.unlock("order-payment-".concat(String.valueOf(id)),String.valueOf(id));
        }

    }

    //退款成功回调

    @Transactional(rollbackFor = Exception.class)
    public void refundsHandle(Long id) {
        while (!redisHandler.lock("order-refunds-".concat(String.valueOf(id)),String.valueOf(id))) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Order order = orderMapper.selectByPrimaryKey(id);
            if (order==null) {
                return;
            }
            if (order.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_COMPLETE.getId())) {
                return;
            }

            //检查是否全部退货完成，订单修改成已完成，部份退不处理
            BigDecimal quantity = BigDecimal.ZERO;
            BigDecimal shippingQuantity = BigDecimal.ZERO;
            BigDecimal returnQuantity = BigDecimal.ZERO;

            List<OrderItem> itemList = orderItemService.getItemList(id);
            for (OrderItem orderItem : itemList) {
                quantity = quantity.add(orderItem.getQuantity());
                shippingQuantity = shippingQuantity.add(orderItem.getShippedQuantity());
                returnQuantity = returnQuantity.add(orderItem.getReturnQuantity());
            }

            //订单已完成
            if (returnQuantity.compareTo(quantity) >= 0) {
                order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
                order.setPaymentStatus(OrderPaymentStatusEnum.PAYMENT_STATUS_REFUND.getId());
                orderMapper.updateByPrimaryKeySelective(order);

                OrderLog orderLog = new OrderLog();
                orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_REFUND.getId());
                orderLog.setContent("退款已完成");
                orderLog.setCreateDate(new Date());
                orderLog.setOrderId(id);
                orderLogService.insertUseGeneratedKeys(orderLog);

                //检查是否收货完毕
                Map<String,Object> params = new HashMap<>();
                params.put("orderId",order.getId());
                List<Return> returnList = returnService.selectList(params);

                for (Return rn:returnList) {
                    returnService.complete(rn.getId());
                }
            }
        } finally {
            redisHandler.unlock("order-refunds-".concat(String.valueOf(id)),String.valueOf(id));
        }

    }


    public Order findBySn(String sn){
        Map<String,Object> params = new HashMap<>();
        params.put("sn",sn);
        List<Order> orderList = super.selectList(params);
        if (orderList.size()>0) {
            return orderList.get(0);
        } else {
            return null;
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void scaner(Long orderId,String sn) {
        Order order = selectByPrimaryKey(orderId);
        try {

            ArrayList itemList = new ArrayList<>();

            BigDecimal quantity = BigDecimal.ZERO;
            List<OrderItem> orderItemList = orderItemService.getItemList(orderId);
            for (OrderItem orderItem:orderItemList) {
                orderItem.setShippedQuantity(orderItem.getQuantity().subtract(orderItem.getReturnQuantity()).subtract(orderItem.getShippedQuantity()));
                quantity = quantity.add(orderItem.getShippedQuantity());
                itemList.add(orderItem);
            }
            if (quantity.compareTo(BigDecimal.ZERO)<=0) {
                throw new CustomException("没有待发商品");
            }

            Warehouse warehouse = shipping(order.getId(), order.getShopId(),
                    DateUtils.truncate(new Date(),Calendar.DATE),order.getWeekTime(), itemList,sn);

            Shipping shipping = new Shipping();
            shipping.setWarehouseId(warehouse.getId());
            shipping.setEnterpriseId(warehouse.getEnterpriseId());
            List<Shipping> shippingList = shippingService.select(shipping);
            for (Shipping shipping1:shippingList) {
                shippingService.shipping(shipping1.getId(),shippingItemService.getItemList(shipping1.getId()));
            }


            received(orderId,false);

        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }

    }

    private void createPromotion(Order order) {
        Member member = memberService.selectByPrimaryKey(order.getMemberId());
        //检查单品的买赠
        for (OrderItem orderItem:order.getItemList()) {
            Product product = productService.selectByPrimaryKey(orderItem.getProductId());

            //检查是否有买赠活动;
            for (Promotion promotion:promotionService.findByProduct(product)) {
                if (promotion.getType().equals(11) && promotion.getMinimumPrice().compareTo(orderItem.getAmount())<=0) {

                    promotionService.createGift(promotion.getId(),member,"c"+order.getSn());

                }
            }
        }

    }

    private void upgrade(Member member,List<Long> ids) {
        if (ids==null) {
            ids = new ArrayList<>();
        }
        Vip vip = vipService.findByNum(member.getEnterpriseId(),member.getVip());
        if (vip==null) {
            vip = new Vip();
            vip.setVip(0);
        }
        if (vip.getVip()>=5) {
            return;
        }
        Vip nextVip = vipService.findByNum(member.getEnterpriseId(),vip.getVip()+1);
        if (nextVip!=null) {
            //消费金额达到升级
            if (nextVip.getMethod().equals(1)) {
                if (member.getAchieve().compareTo(nextVip.getAmount())>=0) {
                    member.setVip(nextVip.getVip());
                    memberService.updateByPrimaryKeySelective(member);
                    upgrade(member,ids);
                }
            }
            //发展人数达到升级
            if (nextVip.getMethod().equals(2)) {
                Map<String,Object> params = new HashMap<>();
                params.put("enterpriseId",member.getEnterpriseId());
                params.put("gvip",member.getVip());
                params.put("promoterId",member.getId());
                Integer w = memberService.selectRowCount(params);
                if (w>=nextVip.getPeople()) {
                    member.setVip(nextVip.getVip());
                    memberService.updateByPrimaryKeySelective(member);
                    upgrade(member,ids);
                }
            }
            //发展人数或消费金额达升级
            if (nextVip.getMethod().equals(4)) {
                if (member.getAchieve().compareTo(nextVip.getAmount())>=0) {
                    member.setVip(nextVip.getVip());
                    memberService.updateByPrimaryKeySelective(member);
                    upgrade(member,ids);
                } else {
                    Map<String, Object> params = new HashMap<>();
                    params.put("enterpriseId", member.getEnterpriseId());
                    params.put("gvip", member.getVip());
                    params.put("promoterId", member.getId());
                    Integer w = memberService.selectRowCount(params);
                    if (w >= nextVip.getPeople()) {
                        member.setVip(nextVip.getVip());
                        memberService.updateByPrimaryKeySelective(member);
                        upgrade(member,ids);
                    }

                }
            }
        }

        ids.add(member.getId());

        if (member.getPromoterId()!=null) {
            if (ids.contains(member.getPromoterId())) {
                return;
            }
            Member promoter = memberService.findById(member.getPromoterId());
            if (promoter!=null) {
                upgrade(promoter,ids);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void addAchieve(Long orderId) {

        Order order = orderMapper.selectByPrimaryKey(orderId);

        if (order.getGroupBuyId()!=null) {
            return;
        }

        if (order.getGiftCardId()!=null) {
            return;
        }

        if (order.getBargainBuyId()!=null) {
            return;
        }


        Distribution defDistribution = distributionService.getDefault(order.getEnterpriseId());
        if (defDistribution==null) {
            return;
        }

        if (defDistribution.getStatus().equals(1)) {
            return;
        }

        order.setItemList(orderItemService.getItemList(orderId));

        BigDecimal achieve = BigDecimal.ZERO;
        for (OrderItem orderItem:order.getItemList()) {
            BigDecimal amount = orderItem.getSubTotal();
            if (orderItem.getIsGift()==false && !orderItem.getSubType().equals(3) && amount.compareTo(BigDecimal.ZERO)>0) {
                Product product = productService.selectByPrimaryKey(orderItem.getProductId());
                Distribution distribution = defDistribution;
                if (product.getDistributionId() != null) {
                    distribution = distributionService.findById(product.getDistributionId());
                }
                if (distribution.getIsAchieve()) {
                    achieve = achieve.add(amount);
                }
            }
        }

        Member member = memberService.findById(order.getMemberId());
        member.setAchieve(member.getAchieve().add(achieve));
        member.setPoint(null);
        member.setFreezePoint(null);
        member.setBalance(null);
        member.setFreezeBalance(null);
        member.setAmount(null);
        memberService.updateByPrimaryKeySelective(member);

        upgrade(member,new ArrayList<>());

    }

    @Transactional(rollbackFor = Exception.class)
    public void startCalcPoint(Long orderId) {

        Order order = orderMapper.selectByPrimaryKey(orderId);

        if (order.getGroupBuyId()!=null) {
            return;
        }

        if (order.getGiftCardId()!=null) {
            return;
        }

        if (order.getBargainBuyId()!=null) {
            return;
        }


        Distribution defDistribution = distributionService.getDefault(order.getEnterpriseId());
        if (defDistribution==null) {
            return;
        }
        if (defDistribution.getStatus().equals(1)) {
            return;
        }

        order.setItemList(orderItemService.getItemList(orderId));

        Member member = memberService.findById(order.getMemberId());
        if (member.getPromoterId()!=null) {
            order.setPromoterId1(member.getPromoterId());
        }

        Member p1 = null;
        if (order.getPromoterId1()!=null) {
            p1 = memberService.findById(order.getPromoterId1());
        }

        Member p2 = null;
        if (p1!=null && p1.getPromoterId()!=null) {
            p2 = memberService.findById(p1.getPromoterId());
            if (p2!=null) {
                order.setPromoterId2(p2.getId());
            }
        }

        Member ag1 = null;
        ag1 = memberService.findByAreaAgent(order.getEnterpriseId(),order.getAreaId());
        if (ag1==null) {
            if (order.getPromoterId1()!=null) {
                ag1 = memberService.getAgent(order.getPromoterId1(), 0);
                if (ag1 != null) {
                    order.setAgentId1(ag1.getId());
                }
            }
        } else {
            order.setAgentId1(ag1.getId());
        }

        BigDecimal a1 = BigDecimal.ZERO;
        BigDecimal a2 = BigDecimal.ZERO;
        BigDecimal t2 = BigDecimal.ZERO;
        BigDecimal d1 = BigDecimal.ZERO;
        BigDecimal my = BigDecimal.ZERO;
        for (OrderItem orderItem:order.getItemList()) {
            BigDecimal amount = orderItem.getSubTotal();
            if (orderItem.getIsGift()==false && !orderItem.getSubType().equals(3) && amount.compareTo(BigDecimal.ZERO)>0) {
                Product product = productService.selectByPrimaryKey(orderItem.getProductId());
                Distribution distribution = defDistribution;
                if (product.getDistributionId() != null) {
                    distribution = distributionService.selectByPrimaryKey(product.getDistributionId());
                }

                distribution.setItemList(distributionItemService.getItemList(distribution.getId()));

                if (p1!=null) {
                    a1 = a1.add(amount.multiply(distribution.getVPercent1(p1.vipObject())));
                }
                if (p2!=null) {
                    a2 = a2.add(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                    t2 = t2.add(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                }
                if (ag1!=null) {
                    d1 = d1.add(amount.multiply(distribution.getVAgent1(ag1.vipObject())));
                }

                my = my.add(amount.multiply(distribution.getGiven()));
            }

        }

        //扣除水票及电子券支付
        Map<String,Object> paymentParams = new HashMap<>();
        paymentParams.put("orderType",0);
        paymentParams.put("orderId",order.getId());
        paymentParams.put("success",1);
        List<Payment> paymentList = paymentService.selectList(paymentParams);
        Distribution distribution = defDistribution;

        for (Payment payment:paymentList) {
            if (payment.getPaymentPluginId().equals("waterTicketPayPlugin")) {
                Attach attach = payment.decodeAttach();
                Product product = productService.selectByPrimaryKey(attach.getProductId());
                if (product.getDistributionId() != null) {
                    distribution = distributionService.findById(product.getDistributionId());
                }

                distribution.setItemList(distributionItemService.getItemList(distribution.getId()));


                BigDecimal amount = payment.getAmount();

                if (p1!=null) {
                    a1 = a1.subtract(amount.multiply(distribution.getVPercent1(p1.vipObject())));
                }
                if (p2!=null) {
                    a2 = a2.subtract(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                    t2 = t2.subtract(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                }
                if (ag1!=null) {
                    d1 = d1.subtract(amount.multiply(distribution.getVAgent1(ag1.vipObject())));
                }
                my = my.subtract(amount.multiply(distribution.getGiven()));
            }

            if (payment.getPaymentPluginId().equals("couponCodePayPlugin")) {
                Attach attach = payment.decodeAttach();
                Product product = productService.selectByPrimaryKey(attach.getProductId());
                if (product.getDistributionId() != null) {
                    distribution = distributionService.selectByPrimaryKey(product.getDistributionId());
                }
                distribution.setItemList(distributionItemService.getItemList(distribution.getId()));

                BigDecimal amount = payment.getAmount();

                if (p1!=null) {
                    a1 = a1.subtract(amount.multiply(distribution.getVPercent1(p1.vipObject())));
                }
                if (p2!=null) {
                    a2 = a2.subtract(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                    t2 = t2.subtract(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                }
                if (ag1!=null) {
                    d1 = d1.subtract(amount.multiply(distribution.getVAgent1(ag1.vipObject())));
                }
                my = my.subtract(amount.multiply(distribution.getGiven()));
            }

        }


        if (a1.compareTo(BigDecimal.ZERO)>0 && p1!=null) {
            order.setRebate1(new BigDecimal(a1.longValue()));
            pointService.addPoint(p1.getId(),a1.longValue(),"1级佣金-贡献会员:".concat(member.getName()),0,order.getId());
            pointService.addFreezePoint(p1.getId(),a1.longValue());
        }


        if (a2.compareTo(BigDecimal.ZERO)>0 && p2!=null && p2.getVvip().compareTo(p1.getVvip())>0) {
            order.setRebate2(new BigDecimal(a2.longValue()));
            pointService.addPoint(p2.getId(),a2.longValue(),"2级佣金-贡献会员:".concat(p1.getName()),0,order.getId());
            pointService.addFreezePoint(p2.getId(),a2.longValue());
        }

        if (t2.compareTo(BigDecimal.ZERO)>0 && t2!=null && p2.getVvip().compareTo(p1.getVvip())==0) {
            order.setRebate2(new BigDecimal(t2.longValue()));
            pointService.addPoint(p2.getId(),t2.longValue(),"2级佣金-贡献会员:".concat(p1.getName()),0,order.getId());
            pointService.addFreezePoint(p2.getId(),t2.longValue());
        }

        if (d1.compareTo(BigDecimal.ZERO)>0 && ag1!=null) {
            order.setAgent1(new BigDecimal(d1.longValue()));
            pointService.addPoint(ag1.getId(),d1.longValue(),"代理佣金-贡献会员:".concat(member.getName()),0,order.getId());
            pointService.addFreezePoint(ag1.getId(),d1.longValue());
        }

        if (my.compareTo(BigDecimal.ZERO)>0 && member!=null) {
            order.setPoint(my.longValue());
            //matchPointService.addMatchPoint(member.getId(),my.longValue(),"购买返利-".concat(order.getTitle()),0,order.getId());
            //pointService.addFreezePoint(member.getId(),my.longValue());
        }

        orderMapper.updateByPrimaryKeySelective(order);

    }

    public void addFoundation(Long orderId) {

        Order order = orderMapper.selectByPrimaryKey(orderId);
        order.setItemList(orderItemService.getItemList(orderId));

        Distribution defDistribution = distributionService.getDefault(order.getEnterpriseId());
        if (defDistribution==null) {
            return;
        }
        if (defDistribution.getStatus().equals(1)) {
            return;
        }

        BigDecimal v1 = BigDecimal.ZERO;
        BigDecimal v2 = BigDecimal.ZERO;
        BigDecimal v3 = BigDecimal.ZERO;
        BigDecimal v4 = BigDecimal.ZERO;
        BigDecimal v5 = BigDecimal.ZERO;

        BigDecimal fund = BigDecimal.ZERO;
        BigDecimal atvy = BigDecimal.ZERO;
        BigDecimal bonus = BigDecimal.ZERO;

        Foundation foundation = foundationService.getInfo(order.getEnterpriseId());

        for (OrderItem orderItem:order.getItemList()) {
            BigDecimal amount = orderItem.getSubTotal();
            if (orderItem.getIsGift()==false && !orderItem.getSubType().equals(3) && amount.compareTo(BigDecimal.ZERO)>0) {

                Product product = productService.selectByPrimaryKey(orderItem.getProductId());
                Distribution distribution = defDistribution;
                if (product.getDistributionId() != null) {
                    distribution = distributionService.findById(product.getDistributionId());
                }

                distribution.setItemList(distributionItemService.getItemList(distribution.getId()));

                Vip vip1 = vipService.findByNum(order.getEnterpriseId(),1);
                if (vip1!=null) {
                    v1 = v1.add(amount.multiply(distribution.getVFund(vip1)));
                }

                Vip vip2 = vipService.findByNum(order.getEnterpriseId(),2);
                if (vip2!=null) {
                    v2 = v2.add(amount.multiply(distribution.getVFund(vip2)));
                }

                Vip vip3 = vipService.findByNum(order.getEnterpriseId(),3);
                if (vip3!=null) {
                    v3 = v3.add(amount.multiply(distribution.getVFund(vip3)));
                }

                Vip vip4 = vipService.findByNum(order.getEnterpriseId(),4);
                if (vip4!=null) {
                    v4 = v4.add(amount.multiply(distribution.getVFund(vip4)));
                }

                Vip vip5 = vipService.findByNum(order.getEnterpriseId(),5);
                if (vip5!=null) {
                    v5 = v5.add(amount.multiply(distribution.getVFund(vip5)));
                }

                fund =  fund.add(amount.multiply(foundation.getFundRate()));
                atvy =  atvy.add(amount.multiply(foundation.getAtvyRate()));
                bonus =  bonus.add(amount.multiply(foundation.getBonusRate()));
            }
        }


        foundationService.addFoundation(foundation.getId(),order.getMemberId(),v1,v2,v3,v4,v5,fund,atvy,bonus);


    }

    @Transactional(rollbackFor = Exception.class)
    public void startDistribution(Long orderId) {

        Order order = orderMapper.selectByPrimaryKey(orderId);

        order.setItemList(orderItemService.getItemList(orderId));

        Enterprise enterprise = enterpriseService.selectByPrimaryKey(order.getEnterpriseId());
        SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
        if (sysMch.getMchType().equals(2)) {

            System.out.println("特约商户，结算货款=======================");

            // 特约商户，结算货款
            Member member = memberService.selectByPrimaryKey(enterprise.getMemberId());
            Map<String,Object> paymentParams = new HashMap<>();
            paymentParams.put("orderType",0);
            paymentParams.put("orderId",order.getId());
            paymentParams.put("success",1);
            List<Payment> paymentList = paymentService.selectList(paymentParams);
            BigDecimal amount = BigDecimal.ZERO;
            for (Payment payment:paymentList) {
                if (    payment.getPaymentPluginId().equals("weixinPayPlugin") ||
                        payment.getPaymentPluginId().equals("weixinMiniPayPlugin") ||
                        payment.getPaymentPluginId().equals("balancePayPlugin")
                        ) {
                    amount = amount.add(payment.getAmount()).subtract(payment.getFee());
                }
            }

            //支付供货商货款
            BigDecimal cost = BigDecimal.ZERO;
            List<OrderItem> orderItemList = order.getItemList();
            String title = null;
            for (OrderItem orderItem:orderItemList) {
                Product product = productService.selectByPrimaryKey(orderItem.getProductId());
                if (product.getPublishType().equals(1)) {
                    BigDecimal subCost = orderItem.calculateSubCost();
                    if (subCost.compareTo(BigDecimal.ZERO)>0) {
                        title = orderItem.getName();
                        cost = cost.add(orderItem.calculateSubCost());
                    }

                }
            }

//          amount = amount.multiply(new BigDecimal(0.006)).setScale(2,BigDecimal.ROUND_HALF_DOWN);
//          cost = cost.multiply(new BigDecimal(0.006)).setScale(2,BigDecimal.ROUND_HALF_DOWN);

            System.out.println("特约商户，结算货款======================="+String.valueOf(amount));

            if (amount.compareTo(BigDecimal.ZERO)>0) {
                depositService.addBalance(member.getId(), amount, 4, "订单-" + order.getTitle(), 0, order.getId());
            }

            if (cost.compareTo(BigDecimal.ZERO)>0) {
                depositService.decBalance(member.getId(), cost, 6, "货款-" + title, 0, order.getId());
            }

            //添加冻结

            BigDecimal freeze = amount.subtract(cost);
            if (freeze.compareTo(BigDecimal.ZERO)>0) {
                Map<String, Object> params = new HashMap<>();
                params.put("id", member.getId());
                params.put("value", freeze);
                memberMapper.addFreezeBalance(params);
            }

        }

        //开始结算佣金 TODO

        order.setIsDistribution(true);
        orderMapper.updateByPrimaryKeySelective(order);

    }


    public Order build(Cart cart) {

        Order order = new Order();
        initOrder(order);
        order.setMemberId(cart.getMemberId());

        Member member = memberService.findById(cart.getMemberId());
        if (member.getAmount().compareTo(BigDecimal.ZERO)>0) {
            order.setIsFirst(false);
        } else {
            order.setIsFirst(true);
        }

        order.setCompanyId(member.getCompanyId());

        order.setPromoterId1(member.getPromoterId());

        List<OrderItem> orderItems = new ArrayList<>();
        for (CartItem cartItem:cart.getItemList()) {
           if (cartItem.getChk()) {
                OrderItem orderItem = new OrderItem();
                Product product = productService.selectByPrimaryKey(cartItem.getProductId());
                order.setEnterpriseId(product.getEnterpriseId());
                orderItem.setSubType(product.getSubType());
                orderItem.setThumbnail(product.getThumbnail());
                orderItem.setName(product.getName());
                orderItem.setUnit(product.getUnit());
                orderItem.setSn(product.getSn());
                orderItem.setSpec(product.getSpec());
                orderItem.setCost(product.getCost());
                orderItem.setDiscount(BigDecimal.ZERO);
                orderItem.setIsGift(false);
                orderItem.setQuantity(new BigDecimal(cartItem.getQuantity()));
                orderItem.setPrice(cartItem.getPrice());
                orderItem.setShippedQuantity(BigDecimal.ZERO);
                orderItem.setReturnQuantity(BigDecimal.ZERO);
                orderItem.setProductId(cartItem.getProductId());
                orderItem.setPromotionId(cartItem.getPromotionId());
                orderItem.setWeight(product.getWeight());
                if (orderItem.getWeight()==null) {
                    orderItem.setWeight(BigDecimal.ZERO);
                }
                orderItems.add(orderItem);
         }
        }
        order.setItemList(orderItems);

        return order;

    }

    public BigDecimal calculateFreight(Order order,Freight freight,Long supplierId) {

        BigDecimal quantity = BigDecimal.ZERO;
        BigDecimal weight = BigDecimal.ZERO;
        for (OrderItem orderItem:order.getItemList()) {
            Product product = productService.selectByPrimaryKey(orderItem.getProductId());
            if (product.getFreightId()!=null &&  product.getFreightId().equals(freight.getId())) {
                if (supplierId == null) {
                    if (product.getSupplierId() == null) {
                        weight = weight.add(product.getWeight().multiply(orderItem.getQuantity()));
                        quantity = quantity.add(orderItem.getQuantity());
                    }
                } else {
                    if (supplierId.equals(product.getSupplierId())) {
                        weight = weight.add(product.getWeight().multiply(orderItem.getQuantity()));
                        quantity = quantity.add(orderItem.getQuantity());
                    }
                }
            }
        }

        BigDecimal fee = freightService.calculate(freight,quantity,weight,order.getAreaId());
        Receiver receiver = receiverService.findById(order.getReceiverId());
        if (receiver!=null && receiver.getLevel()!=null) {
            BigDecimal levelFee = freightService.calculateLevelFee(freight,quantity,receiver.getLevel(),order.getAreaId());
            fee = fee.add(levelFee);
        }

        return fee;
    }

    public void orderPrint(Long orderId) {
        try {

            Order order = orderMapper.selectByPrimaryKey(orderId);

            Enterprise enterprise = enterpriseService.selectByPrimaryKey(order.getEnterpriseId());

            Shop shop = shopService.findByPoint(enterprise, order.getLat(), order.getLng());
            if (shop == null) {
                return;
            }

            if (shop.getPrinterp() != null && shop.getPrinteru() != null) {

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String data =
                        "<MS>6</MS><N>1</N><S2><C>" + "您有新订单了" + "</C></S2>";

                PrinterUtil.print(shop.getPrinteru(), shop.getPrinterp(), data);

            }

        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public int insertOrder(Order order){

        order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_UNCONFIRM.getId());
        order.setPaymentStatus(OrderPaymentStatusEnum.PAYMENT_STATUS_UNPAY.getId());
        order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_UNSHIPPNG.getId());
        order.setDeleted(false);
        order.setIsAllocatedStock(false);
        //todo 计算是否第一单
        order.setIsFirst(false);
        initOrder(order);

        //到店核销
        if (order.getShippingMethod().equals(1)) {
            Shop shop = shopService.selectByPrimaryKey(order.getShopId());
            order.setAreaId(shop.getAreaId());
            order.setAreaName(shop.getAreaName());
            order.setAddress(shop.getAreaName().concat(shop.getAddress()));
            order.setLng(shop.getLng());
            order.setLat(shop.getLat());
        } else {
            //普通快递、同城快送
            if (order.getReceiverId() != null) {
                Receiver receiver = receiverService.selectByPrimaryKey(order.getReceiverId());
                if (receiver != null) {
                    if (!receiver.getMemberId().equals(order.getMemberId())) {
                        throw new CustomException("请选择收货地址");
                    }
                    order.setAreaId(receiver.getAreaId());
                    order.setAreaName(receiver.getAreaName());
                    order.setAddress(receiver.getAddress());
                    order.setConsignee(receiver.getConsignee());
                    order.setPhone(receiver.getPhone());
                    order.setLng(receiver.getLng());
                    order.setLat(receiver.getLat());
                }
            }
        }

        //计算预计送达时间
        order.setEstimateDate(DateUtils.addDays(new Date(),2));
        if (order.getWeekTime()==null) {
            order.setWeekTime(
                    com.rzico.util.DateUtils.getDayOfWeek(order.getEstimateDate())
            );
        }

        //计算订单金额
        BigDecimal amountPayable = order.calculateAmountPayable();
        BigDecimal subPrice = order.calculateSubPrice();
        BigDecimal subQuantity = order.calculateSubQuantity();

//        if (amountPayable.setScale(2,BigDecimal.ROUND_HALF_DOWN).compareTo(order.getAmountPayable().setScale(2,BigDecimal.ROUND_HALF_DOWN)) != 0){
//            throw new CustomException("订单应付金额被篡改");
//        }
//        if (subPrice.setScale(2,BigDecimal.ROUND_HALF_DOWN).compareTo(order.getSubPrice().setScale(2,BigDecimal.ROUND_HALF_DOWN)) != 0){
//            throw new CustomException("订单商品金额被篡改");
//        }
//        if (subQuantity.setScale(2,BigDecimal.ROUND_HALF_DOWN).compareTo(order.getSubQuantity().setScale(2,BigDecimal.ROUND_HALF_DOWN)) != 0){
//            throw new CustomException("订单商品数量被篡改");
//        }


//        System.out.println("=========");
//        System.out.println(JSON.toJSONString(order));
//        System.out.println(String.valueOf(order.getAmountPayable()));
//        System.out.println(String.valueOf(order.calculatePaymentPaid()));

        Member member = memberService.findById(order.getMemberId());
        order.setAmountPaid(order.calculatePaymentPaid());
        if (amountPayable.subtract(order.getAmountPaid()).compareTo(BigDecimal.ZERO)<0) {
            throw new CustomException("不能超额付款");
        }

        if (order.getOrderMethod().equals(0) && "debtPayPlugin".equals(member.getPaymentPluginId())) {

            BigDecimal amount = amountPayable.subtract(order.getAmountPaid());
            if (amount.compareTo(BigDecimal.ZERO)>0) {

                List<OrderPaymentVo> voList = order.getPaymentVo();
                OrderPaymentVo vo = new OrderPaymentVo();
                vo.setAmount(amount);
                vo.setChk(true);
                vo.setPaymentPluginId("debtPayPlugin");
                vo.setBalance(amount);
                vo.setPaymentPluginName("月结客户");
                vo.setQuantity(BigDecimal.ZERO);
                vo.setChk(true);

                Attach attach = new Attach();
                attach.setQuantity(BigDecimal.ZERO);
                attach.setProductId(null);
                attach.setCode("9999");
                attach.setQueue("queue.order.payment");

                vo.setAttach(JSON.toJSONString(attach));

                voList.add(vo);

            }

        }

        order.setSubPrice(subPrice);
        order.setSubQuantity(subQuantity);
        order.setAmountPayable(amountPayable);
        order.setAmountPaid(order.calculatePaymentPaid());
        if (order.getAmountPaid().compareTo(order.getAmountPayable())>=0) {
            order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_CONFIRM.getId());
            order.setPaymentStatus(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId());
        }

        //扣减商品库存
        for (OrderItem sortItem:order.sortItemList()) {
            int r = productService.decStock(sortItem.getProductId(),sortItem.getQuantity());
            if (r==0) {
                throw new CustomException("库存不足");
            }
        }

        Integer rw = insertUseGeneratedKeys(order);

        List<OrderItem> itemList = new ArrayList<>();
        for (OrderItem orderItem : order.getItemList()){
            initOrderItem(orderItem);
            orderItem.setOrderId(order.getId());
            itemList.add(orderItem);
        }
        order.setItemList(itemList);

        Integer num = 0;

        //扣减积分余额
        Integer matchPoint = calculatePoint(order);

        if (matchPoint>0) {
            num++;
            Payment payment = new Payment();
            payment.setCreateDate(new Date());
            payment.setDeleted(false);
            payment.setSn(order.getSn() + "-" + String.valueOf(num));
            payment.setAmount(new BigDecimal(matchPoint/100));
            payment.setRefund(BigDecimal.ZERO);
            payment.setFee(BigDecimal.ZERO);
            payment.setAttach(null);
            payment.setEnterpriseId(order.getEnterpriseId());
            payment.setMemberId(order.getMemberId());
            payment.setExpire(DateUtils.addMinutes(new Date(), 30));
            payment.setStatus(Payment.STATUS_WAITING);
            payment.setType(Payment.TYPE_ORDER);
            payment.setMethod(Payment.METHOD_ONLINE);
            payment.setMemo("购买-" + order.getTitle());
            payment.setWay(1);
            payment.setPaymentPluginId("matchPtPayPlugin");
            payment.setPaymentPluginName("积分");
            payment.setOrderType(OrderTypeEnum.ORDER_TYPE_ORDER.getId());
            payment.setOrderId(order.getId());
            payment.setOrderSn(order.getSn());
            payment.setQuantity(BigDecimal.ZERO);
            Attach attach = new Attach();

            attach.setId(String.valueOf(order.getId()));
            attach.setCode("9999");
            attach.setQueue("queue.order.payment");
            attach.setDescription(order.getTitle());
            payment.setAttach(JSON.toJSONString(attach));
            paymentService.insertUseGeneratedKeys(payment);
            paymentService.execPayment(payment);
        }

        for (OrderPaymentVo vo:order.getPaymentVo()) {
            if (vo.getChk() && vo.getAmount().compareTo(BigDecimal.ZERO)>0) {
                if ("debtPayPlugin".equals(vo.getPaymentPluginId())) {
                     //同时生成应付款
                    Receivable receivable = new Receivable();
                    receivable.setAmount(vo.getAmount());
                    receivable.setAmountPaid(BigDecimal.ZERO);
                    receivable.setQuantityPaid(0);
                    receivable.setQuantity(0);
                    receivable.setType(0);
                    //订单未付款
                    receivable.setStatus(0);
                    receivable.setPaymentPluginId("debtPayPlugin");
                    receivable.setPaymentPluginName("月结");
                    receivable.setDeleted(false);
                    receivable.setMemberId(order.getMemberId());
                    receivable.setEnterpriseId(order.getEnterpriseId());
                    receivable.setOrderId(order.getId());
                    receivable.setOrderType(0);
                    receivable.setOrderSn(order.getSn());
                    receivableService.insertUseGeneratedKeys(receivable);

                } else {

                    num++;
                    Payment payment = new Payment();
                    payment.setCreateDate(new Date());
                    payment.setDeleted(false);
                    payment.setSn(order.getSn() + "-" + String.valueOf(num));
                    payment.setAmount(vo.getAmount());
                    payment.setRefund(BigDecimal.ZERO);
                    payment.setFee(BigDecimal.ZERO);
                    payment.setAttach(vo.getAttach());
                    payment.setEnterpriseId(order.getEnterpriseId());
                    payment.setMemberId(order.getMemberId());
                    payment.setExpire(DateUtils.addMinutes(new Date(), 30));
                    payment.setStatus(Payment.STATUS_WAITING);
                    payment.setType(Payment.TYPE_ORDER);
                    payment.setMethod(Payment.METHOD_ONLINE);
                    payment.setMemo("购买-" + order.getTitle());
                    payment.setWay(1);
                    payment.setPaymentPluginId(vo.getPaymentPluginId());
                    payment.setPaymentPluginName(vo.getPaymentPluginName());
                    payment.setOrderType(OrderTypeEnum.ORDER_TYPE_ORDER.getId());
                    payment.setOrderId(order.getId());
                    payment.setOrderSn(order.getSn());
                    payment.setQuantity(vo.getQuantity());
                    Attach attach = payment.decodeAttach();
                    if (attach == null) {
                        attach = new Attach();
                    }
                    attach.setId(String.valueOf(order.getId()));
                    attach.setCode("9999");
                    attach.setQueue("queue.order.payment");
                    attach.setDescription(order.getTitle());
                    payment.setAttach(JSON.toJSONString(attach));
                    paymentService.insertUseGeneratedKeys(payment);

                    if ("waterTicketPayPlugin".equals(payment.getPaymentPluginId())) {
                        virtualStockService.payment(payment);
                    } else if ("couponCodePayPlugin".equals(payment.getPaymentPluginId())) {
                        couponCodeOrderService.payment(payment);
                    } else {
                        paymentService.execPayment(payment);
                    }

                }

            }
        }

        for (OrderPromotion promotion:order.getPromotions()) {

            //单品活动
            if (promotion.getType().equals(7) || promotion.getType().equals(8) || promotion.getType().equals(9) || promotion.getType().equals(10)) {
                promotionService.decStock(promotion.getPromotionId(),promotion.getQuantity().setScale(0,BigDecimal.ROUND_UP).intValue());
            }
            promotion.setOrderId(order.getId());
            promotion.setCreateDate(new Date());
            orderPromotionService.insertUseGeneratedKeys(promotion);

        }

        if (order.getCouponCodeId()!=null) {

            CouponCode couponCode = couponCodeService.selectByPrimaryKey(order.getCouponCodeId());
            if (couponCode!=null) {
                couponCode.setIsUsed(true);
                couponCode.setUsedDate(new Date());
                couponCodeService.updateByPrimaryKeySelective(couponCode);
            }

        }

        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_CREATE.getId());
        orderLog.setContent("订单已创建");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(order.getId());
        orderLogService.insertUseGeneratedKeys(orderLog);

        member.setAmount(member.getAmount().add(order.getAmountPayable()));
        member.setPoint(null);
        member.setFreezePoint(null);
        member.setBalance(null);
        member.setFreezeBalance(null);
        member.setMatchPoint(null);

        memberService.updateByPrimaryKeySelective(member);

        if (order.getPaymentStatus().equals(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId())) {
            confirm(order.getId(), null);
        }

        try {

            Map<String,Object> content = new HashMap<>();
            content.put("title","订单已创建");
            content.put("itemList",order.getItemList());
            content.put("sn",order.getSn());
            content.put("id",order.getId());
            msgService.sendNotity(member,"msg-order","超时30分钟未付款,订单将自动关闭",JSON.toJSONString(content),null);

            if (order.getPaymentStatus().equals(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId())) {

                orderLog = new OrderLog();
                orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_PAYEMNT.getId());

                orderLog.setContent("订单已付款");
                orderLog.setCreateDate(new Date());
                orderLog.setOrderId(order.getId());
                orderLogService.insertUseGeneratedKeys(orderLog);

                Map<String,Object> contentSucc = new HashMap<>();
                contentSucc.put("title","您已成功下单");
                contentSucc.put("itemList",order.getItemList());
                contentSucc.put("sn",order.getSn());
                contentSucc.put("id",order.getId());
                msgService.sendNotity(member,"msg-order","商家会尽快安排发货，请耐心等待",JSON.toJSONString(contentSucc),null);

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                DecimalFormat df = new DecimalFormat("0.00");
                SysUser sysUser = sysUserService.findById(member.getUserId());
                if (sysUser.getWxmId()!=null) {
                    msgService.sendMiniOrderMsg(sysUser, sdf.format(new Date()), "您已成功下单", order.getTitle(), order.getSn(), df.format(order.getAmountPayable()), "点击查看订单详情");
                }

                if (sysUser.getWxId()!=null) {
                    msgService.sendMPOrderMsg(sysUser, sdf.format(new Date()), "您已成功下单", order.getTitle(), order.getSn(), df.format(order.getAmountPayable()), "点击查看订单详情");
                }

            }

        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return rw;

    }


    @Transactional(rollbackFor = Exception.class)
    public int save(Order order){

        order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_UNCONFIRM.getId());
        order.setPaymentStatus(OrderPaymentStatusEnum.PAYMENT_STATUS_UNPAY.getId());
        order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_UNSHIPPNG.getId());
        order.setDeleted(false);
        order.setIsAllocatedStock(false);
        //todo 计算是否第一单
        order.setIsFirst(false);
        initOrder(order);

        //到店核销
        if (order.getShippingMethod().equals(1)) {
            Shop shop = shopService.selectByPrimaryKey(order.getShopId());
            order.setAreaId(shop.getAreaId());
            order.setAreaName(shop.getAreaName());
            order.setAddress(shop.getAreaName().concat(shop.getAddress()));
            order.setLng(shop.getLng());
            order.setLat(shop.getLat());
        } else {
            //普通快递、同城快送
            if (order.getReceiverId() != null) {
                Receiver receiver = receiverService.selectByPrimaryKey(order.getReceiverId());
                if (receiver != null) {
                    if (!receiver.getMemberId().equals(order.getMemberId())) {
                        throw new CustomException("请选择收货地址");
                    }
                    order.setAreaId(receiver.getAreaId());
                    order.setAreaName(receiver.getAreaName());
                    order.setAddress(receiver.getAddress());
                    order.setConsignee(receiver.getConsignee());
                    order.setPhone(receiver.getPhone());
                    order.setLng(receiver.getLng());
                    order.setLat(receiver.getLat());
                }
            }
        }

        //计算预计送达时间
        order.setEstimateDate(DateUtils.addDays(new Date(),2));
        if (order.getWeekTime()==null) {
            order.setWeekTime(
                    com.rzico.util.DateUtils.getDayOfWeek(order.getEstimateDate())
            );
        }

        //计算订单金额
        BigDecimal amountPayable = order.calculateAmountPayable();
        BigDecimal subPrice = order.calculateSubPrice();
        BigDecimal subQuantity = order.calculateSubQuantity();

//        if (amountPayable.setScale(2,BigDecimal.ROUND_HALF_DOWN).compareTo(order.getAmountPayable().setScale(2,BigDecimal.ROUND_HALF_DOWN)) != 0){
//            throw new CustomException("订单应付金额被篡改");
//        }
//        if (subPrice.setScale(2,BigDecimal.ROUND_HALF_DOWN).compareTo(order.getSubPrice().setScale(2,BigDecimal.ROUND_HALF_DOWN)) != 0){
//            throw new CustomException("订单商品金额被篡改");
//        }
//        if (subQuantity.setScale(2,BigDecimal.ROUND_HALF_DOWN).compareTo(order.getSubQuantity().setScale(2,BigDecimal.ROUND_HALF_DOWN)) != 0){
//            throw new CustomException("订单商品数量被篡改");
//        }


//        System.out.println("=========");
//        System.out.println(JSON.toJSONString(order));
//        System.out.println(String.valueOf(order.getAmountPayable()));
//        System.out.println(String.valueOf(order.calculatePaymentPaid()));

        Member member = memberService.findById(order.getMemberId());
        order.setAmountPaid(order.calculatePaymentPaid());
        if (amountPayable.subtract(order.getAmountPaid()).compareTo(BigDecimal.ZERO)<0) {
            throw new CustomException("不能超额付款");
        }

        if (order.getOrderMethod().equals(0) && "debtPayPlugin".equals(member.getPaymentPluginId())) {

            BigDecimal amount = amountPayable.subtract(order.getAmountPaid());
            if (amount.compareTo(BigDecimal.ZERO)>0) {

                List<OrderPaymentVo> voList = order.getPaymentVo();
                OrderPaymentVo vo = new OrderPaymentVo();
                vo.setAmount(amount);
                vo.setChk(true);
                vo.setPaymentPluginId("debtPayPlugin");
                vo.setBalance(amount);
                vo.setPaymentPluginName("月结客户");
                vo.setQuantity(BigDecimal.ZERO);
                vo.setChk(true);

                Attach attach = new Attach();
                attach.setQuantity(BigDecimal.ZERO);
                attach.setProductId(null);
                attach.setCode("9999");
                attach.setQueue("queue.order.payment");

                vo.setAttach(JSON.toJSONString(attach));

                voList.add(vo);

            }

        }

        order.setSubPrice(subPrice);
        order.setSubQuantity(subQuantity);
        order.setAmountPayable(amountPayable);
        order.setAmountPaid(order.calculatePaymentPaid());
        if (order.getAmountPaid().compareTo(order.getAmountPayable())>=0) {
            order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_CONFIRM.getId());
            order.setPaymentStatus(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId());
        }

        //扣减商品库存
        for (OrderItem sortItem:order.sortItemList()) {
            int r = productService.decStock(sortItem.getProductId(),sortItem.getQuantity());
            if (r==0) {
                throw new CustomException("库存不足");
            }
        }

        Integer rw = insertUseGeneratedKeys(order);

        List<OrderItem> itemList = new ArrayList<>();
        for (OrderItem orderItem : order.getItemList()){
            initOrderItem(orderItem);
            orderItem.setOrderId(order.getId());
            itemList.add(orderItem);
        }
        order.setItemList(itemList);

        Integer num = 0;

        //扣减积分余额
        Integer matchPoint = calculatePoint(order);

        if (matchPoint>0) {
            num++;
            Payment payment = new Payment();
            payment.setCreateDate(new Date());
            payment.setDeleted(false);
            payment.setSn(order.getSn() + "-" + String.valueOf(num));
            payment.setAmount(new BigDecimal(matchPoint/100));
            payment.setRefund(BigDecimal.ZERO);
            payment.setFee(BigDecimal.ZERO);
            payment.setAttach(null);
            payment.setEnterpriseId(order.getEnterpriseId());
            payment.setMemberId(order.getMemberId());
            payment.setExpire(DateUtils.addMinutes(new Date(), 30));
            payment.setStatus(Payment.STATUS_WAITING);
            payment.setType(Payment.TYPE_ORDER);
            payment.setMethod(Payment.METHOD_ONLINE);
            payment.setMemo("购买-" + order.getTitle());
            payment.setWay(1);
            payment.setPaymentPluginId("matchPtPayPlugin");
            payment.setPaymentPluginName("积分");
            payment.setOrderType(OrderTypeEnum.ORDER_TYPE_ORDER.getId());
            payment.setOrderId(order.getId());
            payment.setOrderSn(order.getSn());
            payment.setQuantity(BigDecimal.ZERO);
            Attach attach = new Attach();

            attach.setId(String.valueOf(order.getId()));
            attach.setCode("9999");
            attach.setQueue("queue.order.payment");
            attach.setDescription(order.getTitle());
            payment.setAttach(JSON.toJSONString(attach));
            paymentService.insertUseGeneratedKeys(payment);
            paymentService.execPayment(payment);
        }

        for (OrderPaymentVo vo:order.getPaymentVo()) {
            if (vo.getChk() && vo.getAmount().compareTo(BigDecimal.ZERO)>0) {
                if ("debtPayPlugin".equals(vo.getPaymentPluginId())) {
                    //同时生成应付款
                    Receivable receivable = new Receivable();
                    receivable.setAmount(vo.getAmount());
                    receivable.setAmountPaid(BigDecimal.ZERO);
                    receivable.setQuantityPaid(0);
                    receivable.setQuantity(0);
                    receivable.setType(0);
                    //订单未付款
                    receivable.setStatus(0);
                    receivable.setPaymentPluginId("debtPayPlugin");
                    receivable.setPaymentPluginName("月结");
                    receivable.setDeleted(false);
                    receivable.setMemberId(order.getMemberId());
                    receivable.setEnterpriseId(order.getEnterpriseId());
                    receivable.setOrderId(order.getId());
                    receivable.setOrderType(0);
                    receivable.setOrderSn(order.getSn());
                    receivableService.insertUseGeneratedKeys(receivable);

                } else {

                    num++;
                    Payment payment = new Payment();
                    payment.setCreateDate(new Date());
                    payment.setDeleted(false);
                    payment.setSn(order.getSn() + "-" + String.valueOf(num));
                    payment.setAmount(vo.getAmount());
                    payment.setRefund(BigDecimal.ZERO);
                    payment.setFee(BigDecimal.ZERO);
                    payment.setAttach(vo.getAttach());
                    payment.setEnterpriseId(order.getEnterpriseId());
                    payment.setMemberId(order.getMemberId());
                    payment.setExpire(DateUtils.addMinutes(new Date(), 30));
                    payment.setStatus(Payment.STATUS_WAITING);
                    payment.setType(Payment.TYPE_ORDER);
                    payment.setMethod(Payment.METHOD_ONLINE);
                    payment.setMemo("购买-" + order.getTitle());
                    payment.setWay(1);
                    payment.setPaymentPluginId(vo.getPaymentPluginId());
                    payment.setPaymentPluginName(vo.getPaymentPluginName());
                    payment.setOrderType(OrderTypeEnum.ORDER_TYPE_ORDER.getId());
                    payment.setOrderId(order.getId());
                    payment.setOrderSn(order.getSn());
                    payment.setQuantity(vo.getQuantity());
                    Attach attach = payment.decodeAttach();
                    if (attach == null) {
                        attach = new Attach();
                    }
                    attach.setId(String.valueOf(order.getId()));
                    attach.setCode("9999");
                    attach.setQueue("queue.order.payment");
                    attach.setDescription(order.getTitle());
                    payment.setAttach(JSON.toJSONString(attach));
                    paymentService.insertUseGeneratedKeys(payment);

                    if ("waterTicketPayPlugin".equals(payment.getPaymentPluginId())) {
                        virtualStockService.payment(payment);
                    } else if ("couponCodePayPlugin".equals(payment.getPaymentPluginId())) {
                        couponCodeOrderService.payment(payment);
                    } else {
                        paymentService.execPayment(payment);
                    }

                }

            }
        }

        for (OrderPromotion promotion:order.getPromotions()) {

            //单品活动
            if (promotion.getType().equals(7) || promotion.getType().equals(8) || promotion.getType().equals(9) || promotion.getType().equals(10)) {
                promotionService.decStock(promotion.getPromotionId(),promotion.getQuantity().setScale(0,BigDecimal.ROUND_UP).intValue());
            }
            promotion.setOrderId(order.getId());
            promotion.setCreateDate(new Date());
            orderPromotionService.insertUseGeneratedKeys(promotion);

        }

        if (order.getCouponCodeId()!=null) {

            CouponCode couponCode = couponCodeService.selectByPrimaryKey(order.getCouponCodeId());
            if (couponCode!=null) {
                couponCode.setIsUsed(true);
                couponCode.setUsedDate(new Date());
                couponCodeService.updateByPrimaryKeySelective(couponCode);
            }

        }

        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_CREATE.getId());
        orderLog.setContent("订单已创建");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(order.getId());
        orderLogService.insertUseGeneratedKeys(orderLog);

        member.setAmount(member.getAmount().add(order.getAmountPayable()));
        member.setPoint(null);
        member.setFreezePoint(null);
        member.setBalance(null);
        member.setFreezeBalance(null);
        member.setMatchPoint(null);

        memberService.updateByPrimaryKeySelective(member);

//        if (order.getPaymentStatus().equals(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId())) {
//            confirm(order.getId(), null);
//        }
//
        try {

            Map<String,Object> content = new HashMap<>();
            content.put("title","订单已创建");
            content.put("itemList",order.getItemList());
            content.put("sn",order.getSn());
            content.put("id",order.getId());
            msgService.sendNotity(member,"msg-order","超时30分钟未付款,订单将自动关闭",JSON.toJSONString(content),null);

            if (order.getPaymentStatus().equals(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId())) {

                orderLog = new OrderLog();
                orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_PAYEMNT.getId());

                orderLog.setContent("订单已付款");
                orderLog.setCreateDate(new Date());
                orderLog.setOrderId(order.getId());
                orderLogService.insertUseGeneratedKeys(orderLog);

                Map<String,Object> contentSucc = new HashMap<>();
                contentSucc.put("title","您已成功下单");
                contentSucc.put("itemList",order.getItemList());
                contentSucc.put("sn",order.getSn());
                contentSucc.put("id",order.getId());
                msgService.sendNotity(member,"msg-order","商家会尽快安排发货，请耐心等待",JSON.toJSONString(contentSucc),null);

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                DecimalFormat df = new DecimalFormat("0.00");
                SysUser sysUser = sysUserService.findById(member.getUserId());
                if (sysUser.getWxmId()!=null) {
                    msgService.sendMiniOrderMsg(sysUser, sdf.format(new Date()), "您已成功下单", order.getTitle(), order.getSn(), df.format(order.getAmountPayable()), "点击查看订单详情");
                }

                if (sysUser.getWxId()!=null) {
                    msgService.sendMPOrderMsg(sysUser, sdf.format(new Date()), "您已成功下单", order.getTitle(), order.getSn(), df.format(order.getAmountPayable()), "点击查看订单详情");
                }

            }

        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return rw;

    }


    @Transactional(rollbackFor = Exception.class)
    public int saveAndConfirm(Order order,String sn,SysEmployee sysEmployee,String shippingEmployeeId) {

        int affectCount = insertOrder(order);
        order = findById(order.getId());
        if (order.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_UNCONFIRM.getId())) {
            confirm(order.getId(),sysEmployee);
        }


        List<OrderItem> itemList = new ArrayList<>();

        if (itemList.size()==0) {
            BigDecimal quantity = BigDecimal.ZERO;
            List<OrderItem> orderItemList = orderItemService.getItemList(order.getId());
            for (OrderItem orderItem:orderItemList) {
                orderItem.setShippedQuantity(orderItem.getQuantity().subtract(orderItem.getReturnQuantity()).subtract(orderItem.getShippedQuantity()));
                quantity = quantity.add(orderItem.getShippedQuantity());
                itemList.add(orderItem);
            }
        }

        Warehouse warehouse = shipping(order.getId(), order.getShopId(), order.getOrderDate(),order.getWeekTime(), itemList,sn);

        //人工报单时，自动发货

        if (shippingEmployeeId!=null && !"".equals(shippingEmployeeId)) {
            Shipping shipping = new Shipping();
            shipping.setWarehouseId(warehouse.getId());
            shipping.setEnterpriseId(warehouse.getEnterpriseId());
            List<Shipping> shippingList = shippingService.select(shipping);
            for (Shipping shipping1:shippingList) {
                shippingService.dispatch(shipping1.getId(), order.getShopId(), shippingEmployeeId);
            }
        }

        return affectCount;
    }


    @Transactional(rollbackFor = Exception.class)
    public int saveAndOutStock(Order order,String sn,SysEmployee sysEmployee,String shippingEmployeeId) {
        int affectCount = insertOrder(order);
        order = findById(order.getId());
        if (order.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_UNCONFIRM.getId())) {
            confirm(order.getId(),sysEmployee);
        }

        List<OrderItem> itemList = new ArrayList<>();

        if (itemList.size()==0) {
            BigDecimal quantity = BigDecimal.ZERO;
            List<OrderItem> orderItemList = orderItemService.getItemList(order.getId());
            for (OrderItem orderItem:orderItemList) {
                orderItem.setShippedQuantity(orderItem.getQuantity().subtract(orderItem.getReturnQuantity()).subtract(orderItem.getShippedQuantity()));
                quantity = quantity.add(orderItem.getShippedQuantity());
                itemList.add(orderItem);
            }
        }


        Warehouse warehouse = shippingAndAudit(order.getId(), order.getShopId(), order.getOrderDate(),order.getWeekTime(), itemList,sn);

        //人工报单时，自动发货

        if (shippingEmployeeId!=null && !"".equals(shippingEmployeeId)) {
            Shipping shipping = new Shipping();
            shipping.setWarehouseId(warehouse.getId());
            shipping.setEnterpriseId(warehouse.getEnterpriseId());
            List<Shipping> shippingList = shippingService.select(shipping);
            for (Shipping shipping1:shippingList) {
                shippingService.dispatch(shipping1.getId(), order.getShopId(), shippingEmployeeId);
            }
        }

        return affectCount;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertUseGeneratedKeys(Order order) {
        order.setOrderDate(DateUtils.truncate(order.getOrderDate(),Calendar.DATE));
        int affectCount = super.insertUseGeneratedKeys(order);
        if (affectCount > 0){
            for (OrderItem orderItem : order.getItemList()){
                orderItem.setOrderId(order.getId());
            }
            orderItemService.insertUseGeneratedKeyList(order.getItemList());
        }
        return affectCount;
    }

    /**
     *  确认订单
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int confirm(Long id,SysEmployee sysEmployee) {

        System.out.println("订单确认=======================");
        Order orderConfirm = selectByPrimaryKey(id);
        if (null == orderConfirm){
            throw new CustomException("订单不存在");
        }

        if (orderConfirm.getGiftCardId()!=null) {
            Integer w = giftCardService.updateUsingStatus(orderConfirm.getGiftCardId());
            if (w==0) {
                throw new CustomException("礼卡已使用");
            }
        }

        if (orderConfirm.getBargainBuyId()!=null) {
            bargainPeriodService.addOrder(orderConfirm.getId());
        } else
        if (orderConfirm.getGroupBuyId()!=null) {
            orderConfirm.setOrderStatus(OrderStatusEnum.ORDER_STATUS_UNCONFIRM.getId());
            groupOrderService.addOrder(orderConfirm.getId());
        } else {
            orderConfirm.setOrderStatus(OrderStatusEnum.ORDER_STATUS_CONFIRM.getId());
        }

        orderConfirm.setIsAllocatedStock(true);
        orderConfirm.setIsDistribution(true);
        orderConfirm.setAmountPaid(orderConfirm.getAmountPayable());
        orderConfirm.setPaymentStatus(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId());

        int affectCount = orderMapper.updateByPrimaryKeySelective(orderConfirm);
        if (affectCount > 0){
            //todo 应收账款
            BigDecimal amountPayable = orderConfirm.getAmountPayable().subtract(orderConfirm.getAmountPaid());
            if (amountPayable.compareTo(BigDecimal.ZERO)>0){
                Receivable receivable = new Receivable();
                receivable.setAmount(orderConfirm.getAmountPayable());
                receivable.setAmountPaid(orderConfirm.getAmountPaid());
                receivable.setQuantity(0);
                receivable.setQuantityPaid(0);
                Member member = memberService.selectByPrimaryKey(orderConfirm.getMemberId());
                if ("debtPayPlugin".equals(member.getPaymentPluginId())) {
                    receivable.setPaymentPluginId("debtPayPlugin");
                    receivable.setPaymentPluginName("月结");
                } else {
                    receivable.setPaymentPluginId("cashPayPlugin");
                    receivable.setPaymentPluginName("现金");
                }
                receivable.setType(0);

                int num = orderConfirm.getAmountPaid().compareTo(BigDecimal.ZERO);
                if (num == 0){
                    //订单未付款
                    receivable.setStatus(0);
                }else {
                    //订单部分付款
                    receivable.setStatus(1);
                }
                receivable.setDeleted(false);
                receivable.setMemberId(orderConfirm.getMemberId());
                receivable.setEnterpriseId(orderConfirm.getEnterpriseId());
                receivable.setOrderId(orderConfirm.getId());
                receivable.setOrderType(0);
                receivable.setOrderSn(orderConfirm.getSn());
                receivable.setOfficeId(orderConfirm.getOfficeId());
                receivableService.insertUseGeneratedKeys(receivable);
            }
        }

        //生成应退款，也算是支付完成，转收付款逻辑

        orderConfirm.setItemList(orderItemService.getItemList(orderConfirm.getId()));
        //特约商户结算
        startDistribution(orderConfirm.getId());
        //计算推广佣金
        startCalcPoint(orderConfirm.getId());

        virtualProductService.addOrder(orderConfirm);

        for (OrderItem orderItem:orderConfirm.getItemList()) {

            Product product = productService.findById(orderItem.getProductId());
            Goods goods = goodsMapper.selectByPrimaryKey(product.getGoodsId());
            goods.setTotalSale(goods.getTotalSale()+orderItem.getQuantity().abs().longValue());
            goodsMapper.updateByPrimaryKeySelective(goods);

            if (orderConfirm.getOrderMethod().equals(1)) {
                if (orderItem.getPromotionId()==null && orderItem.getCouponCodeId()==null) {
                    productPriceService.addPrice(orderConfirm.getEnterpriseId(), orderConfirm.getMemberId(), orderItem.getProductId(), orderItem.getPrice());
                }
            }

        }

        //如果自动接单模式，线上订单自动接单
        Enterprise enterprise = enterpriseService.selectByPrimaryKey(orderConfirm.getEnterpriseId());
        if (enterprise.getShippingMethod().equals(1) && orderConfirm.getOrderMethod().equals(0)) {
            Attach attachQueue = new Attach();
            attachQueue.setId(String.valueOf(orderConfirm.getId()));
            attachQueue.setQueue("queue.order.shipping");
            attachQueue.setCode("0000");
            attachQueue.setDescription("自动接单");
            Message message = MessageBuilder
                    .withBody(JSON.toJSONString(attachQueue).getBytes())
                    .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                    .build();
            CorrelationData correlationData = new CorrelationData();
            correlationData.setId(UUID.randomUUID().toString());
            rabbitTemplate.convertAndSend("directExchange", attachQueue.getQueue() + ".key", message, correlationData);
        }

        if (!orderConfirm.getPaymentStatus().equals(OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId())) {
            OrderLog orderLog = new OrderLog();
            orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_CONFIRM.getId());
            orderLog.setContent("订单已确认");
            orderLog.setCreateDate(new Date());
            orderLog.setOrderId(orderConfirm.getId());
            if (sysEmployee!=null) {
                orderLog.setContent("订单已确认,审核:"+sysEmployee.getName());
                orderLog.setOperator(sysEmployee.getUserId());
            }
            orderLogService.insertUseGeneratedKeys(orderLog);
        }

        //向店主推送

        if (orderConfirm.getOrderMethod().equals(0)) {
            Map<String, Object> content = new HashMap<>();
            content.put("title", "您有新订单了");
            content.put("itemList", orderConfirm.getItemList());
            content.put("sn", orderConfirm.getSn());
            content.put("id", orderConfirm.getId());

            Map<String,Object> params = new HashMap<>();
            params.put("mchId",enterprise.getMchId());
            params.put("userType",1);
            List<SysUser> sysUserList = sysUserService.selectList(params);
            for (SysUser sysUser:sysUserList) {
                Boolean hasAudit = false;
                List<SysMenu> list = sysUser.getMenuList();
                for (SysMenu menu : list) {
                    if (menu.getPermission()!=null && menu.getPermission().equals("order.audit")) {
                        hasAudit = true;
                        break;
                    }
                }
                if (hasAudit) {
                    msgService.sendNotity(sysUser, "msg-order", "您有新订单了，请尽快处理", JSON.toJSONString(content), "h1");
                }
            }

            orderPrint(orderConfirm.getId());
        }

        return affectCount;

    }

    private void removePromotion(List<OrderPromotion> promotionList,Promotion promotion) {
        for (OrderPromotion op:promotionList) {
            Promotion pm = op.getPromotion();
            if (pm.getId().equals(promotion.getId())) {
                promotionList.remove(op);
                break;
            }
        }
    }

    //检查是否存，并活动力度是否更大
    private Boolean checkPromotionExists(List<OrderPromotion> promotionList,Promotion promotion) {

        Promotion prom = null;
//        BigDecimal maxPrice=BigDecimal.ZERO;
        for (OrderPromotion p:promotionList) {
            Promotion pm = p.getPromotion();
            if (pm.getType().equals(promotion.getType())) {
                prom = pm;
            }
            //不叠加时，获取力度最大的活动 TODO 暂不做全场活动叠加规则
//            if (maxPrice.compareTo(pm.getMinimumPrice())<0) {
//                maxPrice = pm.getMinimumPrice();
//            }
        }

        if (prom==null) {
            return true;
        }

        //判断满减力度
        if (promotion.getType().equals(3)) {
            if (promotion.getMinimumPrice().compareTo(prom.getMinimumPrice())>0) {
                removePromotion(promotionList, prom);
                return promotion.getAmount().compareTo(prom.getAmount()) >= 0;
            }
        }

        //判断满折力度
        if (promotion.getType().equals(4)) {
            if (promotion.getMinimumPrice().compareTo(prom.getMinimumPrice())>0) {
                removePromotion(promotionList, prom);
                return promotion.getAgioRate().compareTo(prom.getAgioRate()) >= 0;
            }
        }

        //判断满赠
        if (promotion.getType().equals(5)) {
            if (promotion.getMinimumPrice().compareTo(prom.getMinimumPrice())>0) {
                removePromotion(promotionList, prom);
                return promotion.getMinimumPrice().compareTo(prom.getMinimumPrice()) >= 0;
            }
        }

        //判断满包邮
        if (promotion.getType().equals(6)) {
            removePromotion(promotionList,prom);
            return promotion.getMinimumPrice().compareTo(prom.getMinimumPrice())>=0;
        }

        //判断消费送
        if (promotion.getType().equals(1)) {
            if (promotion.getMinimumPrice().compareTo(prom.getMinimumPrice())>0) {
                removePromotion(promotionList, prom);
                return promotion.getMinimumPrice().compareTo(prom.getMinimumPrice()) >= 0;
            }
        }

        return false;
    }

    private Boolean checkTargetExists(List<CouponTarget> targetList,Long id) {
        for (CouponTarget t:targetList) {
            if (t.getTargetId().equals(id)) {
                return true;
            }
        }
        return false;
    }


    //获取订单支持的配送方式
    public String getShippingMethods(Order order) {
        List<String> ss = new ArrayList<>();
        ss.add("0");
        ss.add("1");
        ss.add("2");
        for (OrderItem orderItem:order.getItemList()) {
            Product product = productService.selectByPrimaryKey(orderItem.getProductId());

            //没有指定只支持快递
            if (product.getShippingMethod()==null) {
                product.setShippingMethod("0");
            }

            if (product.getShippingMethod().indexOf("0")<0) {
                ss.remove("0");
            }

            if (product.getShippingMethod().indexOf("1")<0) {
                ss.remove("1");
            }

            if (product.getShippingMethod().indexOf("2")<0) {
                ss.remove("2");
            }

        }
        return String.join(",",ss);
    }

    /**
     * 计算订单促销活动
     * @param order
     * 人工报单时，都不再参加任何活动，前端指定的价格为准
     * @return
     */

    public Order calculate(Order order) {

        initOrder(order);

        List<OrderItem> list = order.getItemList();
        if (null == list || list.size() == 0){
            throw new CustomException("订单明细为空");
        }
        Member member = memberService.findById(order.getMemberId());
        if (member.getAmount().compareTo(BigDecimal.ZERO)>0) {
            order.setIsFirst(false);
        } else {
            order.setIsFirst(true);
        }
        order.setCompanyId(member.getCompanyId());

        List<OrderItem> giftItems = new ArrayList<>();
        List<Long> freights = new ArrayList<>();
        List<Long> suppliers = new ArrayList<>();

        for (OrderItem orderItem:order.getItemList()) {

            Product product = productService.selectByPrimaryKey(orderItem.getProductId());
            initOrderItem(orderItem);
            orderItem.setSubType(product.getSubType());

            order.setEnterpriseId(product.getEnterpriseId());

            if (product.getFreightId() != null) {
                if (!freights.contains(product.getFreightId())) {
                    freights.add(product.getFreightId());
                }
            }

            if (product.getSupplierId() != null) {
                if (!suppliers.contains(product.getSupplierId())) {
                    suppliers.add(product.getSupplierId());
                }
            }

        }

        //清除赠品
        List<OrderItem> orderItems = new ArrayList<>();
        for (OrderItem orderItem:order.getItemList()) {
            if (orderItem.getIsGift()==null) {
                orderItem.setIsGift(false);
            }
            if (orderItem.getIsGift()==false) {
                orderItems.add(orderItem);
            }
        }
        order.setItemList(orderItems);

        if (!order.getOrderMethod().equals(1)) {


            for (OrderItem orderItem:order.getItemList()) {

                Product product = productService.selectByPrimaryKey(orderItem.getProductId());
                initOrderItem(orderItem);
                orderItem.setSubType(product.getSubType());

                order.setEnterpriseId(product.getEnterpriseId());

                if (order.getGiftCardId()==null && order.getGroupBuyId()==null) {
                    orderItem.setPrice(product.getMemberPrice(member));


                    //检查单品活动
                    Promotion promotion = null;
                    if (orderItem.getPromotionId()!=null) {
                        promotion = promotionService.selectByPrimaryKey(orderItem.getPromotionId());
                    } else {
                        //默认走会员价
                        BigDecimal price = orderItem.getPrice();
                        for (Promotion pro:promotionService.findByProduct(product)) {
                            if (pro.getStock()==null) {
                                pro.setStock(0);
                            }
                            if (pro.getFirsted()==null) {
                                pro.setFirsted(false);
                            }
                            //新人价 一般是最低
                            if (pro.getType().equals(10) && order.getIsFirst() && pro.getAmount().compareTo(price)<0  && new BigDecimal(pro.getStock()).compareTo(orderItem.getQuantity())>=0) {
                                price = pro.getAmount();
                                promotion = pro;
                            }
                            //秒杀价 力度很大
                            if (pro.getType().equals(8) && ((order.getIsFirst() && pro.getFirsted()) || pro.getFirsted()==false) && pro.getAmount().compareTo(price)<0 && new BigDecimal(pro.getStock()).compareTo(orderItem.getQuantity())>=0) {
                                price = pro.getAmount();
                                promotion = pro;
                            }

                            //第二件单价 促销活动，会员日常活动力度大
                            if (pro.getType().equals(9) && ((order.getIsFirst() && pro.getFirsted()) || pro.getFirsted()==false) ) {
                                BigDecimal total = product.getPrice().multiply(orderItem.getQuantity());

                                BigDecimal halfQry = orderItem.getQuantity().divide(new BigDecimal(2),0,BigDecimal.ROUND_DOWN);
                                if (new BigDecimal(pro.getStock()).compareTo(halfQry)>=0) {

                                    BigDecimal hasfPrc = product.getPrice().multiply(halfQry).divide(new BigDecimal(2)).setScale(2, BigDecimal.ROUND_HALF_DOWN);

                                    total = total.subtract(hasfPrc);

                                    BigDecimal prc = total.divide(orderItem.getQuantity(), 2, BigDecimal.ROUND_HALF_DOWN);
                                    if (prc.compareTo(price) < 0) {
                                        promotion = pro;
                                    }
                                }
                            }

                            //买送 常规活动
                            if (pro.getType().equals(7) && ((order.getIsFirst() && pro.getFirsted()) || pro.getFirsted()==false) ) {
                                BigDecimal rate = orderItem.getQuantity().divide(pro.getMinimumPrice(),0,BigDecimal.ROUND_DOWN);
                                BigDecimal give = rate.multiply(pro.getAmount()).setScale(0,BigDecimal.ROUND_DOWN);

                                if (new BigDecimal(pro.getStock()).compareTo(give)<0) {
                                    give = new BigDecimal(pro.getStock());
                                }
                                if (give.compareTo(BigDecimal.ZERO)>0) {
                                    BigDecimal total = product.getPrice().multiply(orderItem.getQuantity());
                                    BigDecimal prc = total.divide(orderItem.getQuantity().add(give), 2, BigDecimal.ROUND_HALF_DOWN);
                                    if (prc.compareTo(price) < 0) {
                                        promotion = pro;
                                    }
                                }

                            }
                        }
                    }

                    //执行活动

                    if (promotion!=null) {

                        if (promotion.getStock()==null) {
                            promotion.setStock(0);
                        }
                        //新人价 一般是最低
                        if (promotion.getType().equals(10)) {
                            orderItem.setPrice(promotion.getAmount());
                            orderItem.setPromotionId(promotion.getId());
                            addPromotion(order,promotion,orderItem.getQuantity());
                        }
                        //秒杀价 力度很大
                        if (promotion.getType().equals(8)) {
                            orderItem.setPrice(promotion.getAmount());
                            orderItem.setPromotionId(promotion.getId());
                            addPromotion(order,promotion,orderItem.getQuantity());
                        }

                        //第二件单价 促销活动，会员日常活动力度大
                        if (promotion.getType().equals(9)) {
                            BigDecimal total = product.getPrice().multiply(orderItem.getQuantity());

                            BigDecimal halfQry = orderItem.getQuantity().divide(new BigDecimal(2),0,BigDecimal.ROUND_DOWN);

                            BigDecimal hasfPrc = product.getPrice().multiply(halfQry).divide(new BigDecimal(2),2,BigDecimal.ROUND_HALF_DOWN);

                            total = total.subtract(hasfPrc);

                            BigDecimal prc = total.divide(orderItem.getQuantity(),2,BigDecimal.ROUND_HALF_DOWN);

                            orderItem.setPrice(prc);
                            orderItem.setPromotionId(promotion.getId());
                            addPromotion(order,promotion,halfQry);
                        }

                        //买送 常规活动
                        if (promotion.getType().equals(7)) {
                            BigDecimal rate = orderItem.getQuantity().divide(promotion.getMinimumPrice(),0,BigDecimal.ROUND_DOWN);
                            BigDecimal give = rate.multiply(promotion.getAmount()).setScale(0,BigDecimal.ROUND_DOWN);

                            if (new BigDecimal(promotion.getStock()).compareTo(give)<0) {
                                give = new BigDecimal(promotion.getStock());
                            }

                            if (give.compareTo(BigDecimal.ZERO)>0) {

                                OrderItem giftItem = new OrderItem();
                                giftItem.setThumbnail(orderItem.getThumbnail());
                                giftItem.setName(orderItem.getName());
                                giftItem.setUnit(orderItem.getUnit());
                                giftItem.setSn(orderItem.getSn());
                                giftItem.setSpec(orderItem.getSpec());
                                giftItem.setCost(orderItem.getCost());
                                giftItem.setDiscount(BigDecimal.ZERO);
                                giftItem.setIsGift(true);
                                giftItem.setQuantity(give);
                                giftItem.setPrice(BigDecimal.ZERO);
                                giftItem.setShippedQuantity(BigDecimal.ZERO);
                                giftItem.setReturnQuantity(BigDecimal.ZERO);
                                giftItem.setProductId(orderItem.getProductId());
                                giftItem.setPromotionId(promotion.getId());
                                giftItem.setSubType(product.getSubType());
                                giftItem.setWeight(product.getWeight());
                                if (giftItem.getWeight()==null) {
                                    giftItem.setWeight(BigDecimal.ZERO);
                                }
                                giftItems.add(giftItem);

                                orderItem.setPromotionId(promotion.getId());
                                addPromotion(order, promotion, promotion.getAmount());
                            }
                        }
                    }
                }

                if (!order.getIsFirst()) {

                    //客户历史价格小于当前售价时，
                    BigDecimal price = productPriceService.getPrice(order.getEnterpriseId(),order.getMemberId(),orderItem.getProductId());
                    if (price!=null && price.compareTo(orderItem.getPrice())<0) {
                        orderItem.setPrice(price);
                    }

                }

            }

        }

        order.setSubQuantity(order.calculateSubQuantity());
        order.setSubPrice(order.calculateSubPrice());


        //计算运费
        log.info("开始计算运费");
        BigDecimal freightFee = BigDecimal.ZERO;
        if (order.getGiftCardId()==null) {
            if (order.getReceiverId() != null) {
                for (Long freightId : freights) {
                    if (freightId != null && freightId > 0L) {
                        Freight freight = freightService.findById(freightId);
                        if (freight != null) {
                            for (Long suppierId : suppliers) {
                                freightFee = freightFee.add(calculateFreight(order, freight, suppierId));
                            }
                        }
                    }
                }
            }
        }

        order.setFreight(freightFee);

        //开始检查可用优惠券
        if (order.getGroupBuyId()==null && order.getGiftCardId()==null && order.getBargainBuyId()==null) {
            List<CouponCodeVo> couponCodeVos = couponCodeService.getCouponCodeVoList(order.getMemberId());
            BigDecimal couponDiscount = BigDecimal.ZERO;
            for (CouponCodeVo vo : couponCodeVos) {

                Boolean isVaild = false;

                Coupon coupon = couponService.findById(vo.getCouponId());
                if (!coupon.getEnterpriseId().equals(order.getEnterpriseId())) {
                    continue;
                }

                BigDecimal amount = BigDecimal.ZERO;
                //通用券
                if (vo.getTargetType().equals(0)) {
                    amount = order.calculateNoPromotionSubPrice();
                    isVaild = true;
                }
                //品牌券
                if (vo.getTargetType().equals(1)) {
                    BigDecimal brandAmount = BigDecimal.ZERO;
                    for (OrderItem orderItem : order.getItemList()) {
                        Product product = productService.findById(orderItem.getProductId());
                        if (product.getBrandId() != null) {
                            if (checkTargetExists(coupon.getTargets(), product.getBrandId())) {
                                brandAmount = brandAmount.add(orderItem.getAmount());
                                isVaild = true;
                            }
                        }
                    }
                    amount = brandAmount;
                }
                //会员券
                if (vo.getTargetType().equals(2)) {
                    amount = new BigDecimal(-1);
                    BigDecimal vipAmount = BigDecimal.ZERO;

                    Vip vip = vipService.findByNum(order.getEnterpriseId(), member.getVip());
                    if (vip != null) {
                        if (checkTargetExists(coupon.getTargets(), vip.getId())) {
                            vipAmount = order.calculateSubPrice();
                            isVaild = true;
                        }
                    }
                    amount = vipAmount;
                }
                //分类券
                if (vo.getTargetType().equals(3)) {
                    BigDecimal categoryAmount = BigDecimal.ZERO;
                    for (OrderItem orderItem : order.getItemList()) {
                        Product product = productService.findById(orderItem.getProductId());
                        if (product.getProductCategoryId() != null) {
                            for (CouponTarget target : coupon.getTargets()) {
                                //判断这个分类下，这个商品是否存在
                                Map<String, Object> params = new HashMap<>();
                                params.put("treePath", target.getTargetId());
                                params.put("id", orderItem.getProductId());
                                Integer rw = productService.selectRowCount(params);
                                if (rw > 0) {
                                    isVaild = true;
                                    categoryAmount = categoryAmount.add(orderItem.getAmount());
                                    break;
                                }
                            }
                        }
                    }
                    amount = categoryAmount;
                }
                //商品券
                if (vo.getTargetType().equals(4)) {
                    BigDecimal productAmount = BigDecimal.ZERO;
                    for (OrderItem orderItem : order.getItemList()) {
                        Product product = productService.selectByPrimaryKey(orderItem.getProductId());
                        if (checkTargetExists(coupon.getTargets(),product.getGoodsId())) {
                            isVaild = true;
                            productAmount = productAmount.add(orderItem.getAmount());
                        }

                    }
                    amount = productAmount;
                }
                if (isVaild && vo.getMinimumPrice().compareTo(amount) <= 0) {

                    BigDecimal d = BigDecimal.ZERO;

                    //满减
                    if (vo.getType().equals(0)) {
                        d = vo.getAmount();
                    }
                    //折扣券
                    if (vo.getType().equals(1)) {
                        d = amount.multiply(new BigDecimal(100).subtract(vo.getAmount())).multiply(new BigDecimal("0.01")).setScale(2, BigDecimal.ROUND_HALF_DOWN);
                    }

                    if (d.compareTo(couponDiscount) > 0) {
                        couponDiscount = d;
                        order.setCouponCodeId(vo.getId());
                    }

                }

            }

            //开始全场活动
            log.info("开始全场活动");
            List<Promotion> promotions = promotionService.findByTheWhole(order.getEnterpriseId());

            for (Promotion promotion : promotions) {
                BigDecimal amount = BigDecimal.ZERO;
                if (promotion.getOverlying() == null) {
                    promotion.setOverlying(false);
                }
                if (promotion.getOverlying() || promotion.getType().equals(6)) {
                    amount = order.calculateSubPrice();
                } else {
                    amount = order.calculateNoPromotionSubPrice().subtract(couponDiscount);
                }
                if (promotion.getFirsted() == null) {
                    promotion.setFirsted(false);
                }
                //满减
                if (promotion.getType().equals(3) && ((order.getIsFirst() && promotion.getFirsted()) || promotion.getFirsted() == false) && amount.compareTo(promotion.getMinimumPrice()) >= 0) {
                    if (checkPromotionExists(order.getPromotions(), promotion)) {
                        addPromotion(order, promotion, BigDecimal.ZERO);
                    }
                }
                //满折
                if (promotion.getType().equals(4) && ((order.getIsFirst() && promotion.getFirsted()) || promotion.getFirsted() == false) && amount.compareTo(promotion.getMinimumPrice()) >= 0) {
                    if (checkPromotionExists(order.getPromotions(), promotion)) {
                        addPromotion(order, promotion, BigDecimal.ZERO);
                    }
                }
                //满赠
                if (promotion.getType().equals(5) && ((order.getIsFirst() && promotion.getFirsted()) || promotion.getFirsted() == false) && amount.compareTo(promotion.getMinimumPrice()) >= 0) {
                    if (checkPromotionExists(order.getPromotions(), promotion)) {
                        addPromotion(order, promotion, BigDecimal.ZERO);
                    }
                }
                //满包邮
                if (promotion.getType().equals(6) && ((order.getIsFirst() && promotion.getFirsted()) || promotion.getFirsted() == false) && amount.compareTo(promotion.getMinimumPrice()) >= 0) {
                    if (checkPromotionExists(order.getPromotions(), promotion)) {
                        addPromotion(order, promotion, BigDecimal.ZERO);
                    }
                }
                //消费送
                if (promotion.getType().equals(1) && ((order.getIsFirst() && promotion.getFirsted()) || promotion.getFirsted() == false) && amount.compareTo(promotion.getMinimumPrice()) >= 0) {
                    if (checkPromotionExists(order.getPromotions(), promotion)) {
                        addPromotion(order, promotion, BigDecimal.ZERO);
                    }
                }

            }

            BigDecimal theWholeDiscount = BigDecimal.ZERO;
            for (OrderPromotion op : order.getPromotions()) {
                Promotion promotion = op.getPromotion();
                BigDecimal amount = BigDecimal.ZERO;
                if (promotion.getOverlying() == null) {
                    promotion.setOverlying(false);
                }
                if (promotion.getOverlying()) {
                    amount = order.calculateSubPrice();
                } else {
                    amount = order.calculateNoPromotionSubPrice();
                }
                //满减
                if (promotion.getType().equals(3)) {
                    theWholeDiscount = theWholeDiscount.add(promotion.getAmount());
                }
                //满折
                if (promotion.getType().equals(4)) {
                    theWholeDiscount = theWholeDiscount.add(amount.multiply(new BigDecimal(100).subtract(promotion.getAgioRate())).multiply(new BigDecimal("0.01")).setScale(2, BigDecimal.ROUND_HALF_DOWN));
                }
                //满赠
                if (promotion.getType().equals(5)) {
                    if (promotion.getGiftType().equals(0)) {
                        for (PromotionGift gift : promotion.getGifts()) {
                            Product product = productService.selectByPrimaryKey(gift.getGiftId());
                            if (product != null) {
                                OrderItem orderItem = new OrderItem();
                                orderItem.setThumbnail(product.getThumbnail());
                                orderItem.setName(product.getName());
                                orderItem.setUnit(product.getUnit());
                                orderItem.setSn(product.getSn());
                                orderItem.setSpec(product.getSpec());
                                orderItem.setCost(product.getCost());
                                orderItem.setDiscount(BigDecimal.ZERO);
                                orderItem.setIsGift(true);
                                orderItem.setQuantity(new BigDecimal(gift.getQuantity()));
                                orderItem.setPrice(BigDecimal.ZERO);
                                orderItem.setShippedQuantity(BigDecimal.ZERO);
                                orderItem.setReturnQuantity(BigDecimal.ZERO);
                                orderItem.setProductId(gift.getGiftId());
                                orderItem.setPromotionId(promotion.getId());
                                orderItem.setSubType(product.getSubType());
                                orderItem.setWeight(product.getWeight());
                                if (orderItem.getWeight()==null) {
                                    orderItem.setWeight(BigDecimal.ZERO);
                                }
                                giftItems.add(orderItem);
                            }
                        }
                    } else {
                        //赠券订单完成后再处理
                    }
                }
                //满包邮
                if (promotion.getType().equals(6)) {
                    order.setFreight(BigDecimal.ZERO);
                }
                //消费送
                if (promotion.getType().equals(1)) {
                    //消费送，订单完成后处理
                }

            }

            orderItems.addAll(giftItems);

            //加上优惠券后再  判断

            theWholeDiscount = theWholeDiscount.add(couponDiscount);

            if (theWholeDiscount.compareTo(order.calculateSubPrice()) >= 0) {
                order.setDiscount(order.calculateSubPrice());
            } else {
                order.setDiscount(theWholeDiscount);
            }

            order.setSubQuantity(order.calculateSubQuantity());
            order.setSubPrice(order.calculateSubPrice());


            //end全场活动
        } else {

            order.setDiscount(BigDecimal.ZERO);

            //团购优惠计算

            if (order.getGroupBuyId()!=null) {
                GroupBuy groupBuy = groupBuyService.selectByPrimaryKey(order.getGroupBuyId());
                BigDecimal discount = order.calculateSubPrice().subtract(groupBuy.getPrice());
                if (discount.compareTo(BigDecimal.ZERO)>0) {
                    order.setDiscount(discount);
                }

            }

            //砍价优惠计算

            if (order.getBargainBuyId()!=null) {
                BargainBuy bargainBuy = bargainBuyService.selectByPrimaryKey(order.getBargainBuyId());
                BigDecimal discount = order.calculateSubPrice().subtract(bargainBuy.getPrice());
                if (discount.compareTo(BigDecimal.ZERO)>0) {
                    order.setDiscount(discount);
                }

            }

        }


        //店铺优惠+抹零，按交易金额分滩到每个商品
        log.info("按交易金额分滩到每个商品");
        BigDecimal discount = order.getDiscount().subtract(order.getOffsetAmount());
        if (discount.compareTo(BigDecimal.ZERO)>0) {
            BigDecimal balance = discount;
            BigDecimal totalAmount = order.getSubPrice();
            //开始分摊活动费用
            for (OrderItem orderItem : order.getItemList()) {
                if (orderItem.getIsGift() == false) {
                    BigDecimal d = orderItem.getAmount().
                            multiply(discount).
                            divide(totalAmount, 2, BigDecimal.ROUND_DOWN);
                    orderItem.setIsGift(false);
                    orderItem.setDiscount(d);
                    balance = balance.subtract(d);
                }
            }
            //结余没分完的，分到第一个商品中
            OrderItem orderItem = order.getItemList().get(0);
            orderItem.setDiscount(orderItem.getDiscount().add(balance));
        }

        order.setAmountPayable(order.calculateAmountPayable());
        order.setAmountPaid(BigDecimal.ZERO);
        return order;

    }

    //生成付款单
//    @Transactional(rollbackFor = Exception.class)
    public Payment payment(Order order,String sn) {

        Payment payment = new Payment();
        payment.setCreateDate(new Date());
        payment.setDeleted(false);
        payment.setSn(sn);
        payment.setAmount(order.getAmountPayable().subtract(order.getAmountPaid()));
        payment.setRefund(BigDecimal.ZERO);
        Attach attach = new Attach();
        attach.setId(String.valueOf(order.getId()));
        attach.setCode("9999");
        attach.setQueue("queue.order.payment");
        attach.setDescription(order.getTitle());
        payment.setAttach(JSON.toJSONString(attach));
        payment.setEnterpriseId(order.getEnterpriseId());
        payment.setMemberId(order.getMemberId());
        payment.setExpire(DateUtils.addMinutes(new Date(),30));
        payment.setStatus(Payment.STATUS_WAITING);
        payment.setType(Payment.TYPE_ORDER);
        payment.setMethod(Payment.METHOD_ONLINE);
        payment.setMemo("订单-"+order.getTitle());
        payment.setWay(1);
        payment.setOrderType(OrderTypeEnum.ORDER_TYPE_ORDER.getId());
        payment.setOrderId(order.getId());
        payment.setOrderSn(order.getSn());
        payment.setFee(BigDecimal.ZERO);

        paymentService.insertUseGeneratedKeys(payment);
        return payment;

    }

    private Boolean checkCardTagExists(List<Tag> tags,List<Tag> cardTags) {
        if (cardTags.size()==0) {
            return true;
        }
        for (Tag tag:tags) {
            for (Tag g:cardTags) {
                if (tag.getId().equals(g.getId())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 订单支付
     * @param order
     * @return
     */

    public List<OrderPaymentVo> calculatePayment(Order order) {

        List<OrderPaymentVo> list = new ArrayList<>();

        //检查能使用的电子水票
        List<VirtualStock> virtualStockList= virtualStockService.findByMember(order.getMemberId());
        for (VirtualStock virtualStock:virtualStockList) {

            //计算能使用的金额
            BigDecimal amount = BigDecimal.ZERO;
            BigDecimal quantity = BigDecimal.ZERO;
            BigDecimal stock = virtualStock.getStock();

            Long productId = null;

            for (OrderItem orderItem:order.getItemList()) {
                if ((orderItem.getSubType().equals(0) || orderItem.getSubType().equals(4)) && !orderItem.getSubType().equals(3) && orderItem.getIsGift()==false) {
                    Product product = productService.findById(orderItem.getProductId());
                    if (bomService.checkCanUse(virtualStock.getProductId(), product.getId())) {
                        if (stock.compareTo(orderItem.getQuantity()) >= 0) {
                            amount = amount.add(orderItem.getSubTotal());
                            quantity = quantity.add(orderItem.getQuantity());
                        } else {
                            quantity = stock;
                            amount = amount.add(orderItem.getPrice().multiply(stock).subtract(orderItem.getDiscount()).setScale(2, BigDecimal.ROUND_HALF_DOWN));
                        }
                        stock = stock.subtract(quantity);
                        productId = product.getId();
                    }
                }
            }

            if (amount.compareTo(BigDecimal.ZERO)>0) {

                OrderPaymentVo vo = new OrderPaymentVo();
                vo.setAmount(amount);
                vo.setChk(true);
                vo.setPaymentPluginId("waterTicketPayPlugin");
                vo.setBalance(amount);
                vo.setPaymentPluginName(virtualStock.getProductName());
                vo.setQuantity(quantity);

                Attach attach = new Attach();
                attach.setCardId(String.valueOf(virtualStock.getId()));
                attach.setQuantity(quantity);
                attach.setProductId(productId);
                attach.setCode("9999");
                attach.setQueue("queue.order.payment");
                attach.setDescription(virtualStock.getProductName());

                vo.setAttach(JSON.toJSONString(attach));

                list.add(vo);

            }

        }

        //检查能否使用兑换券
        for (OrderItem orderItem:order.getItemList()) {
            if (orderItem.getIsGift()==false) {
                //计算能使用的金额
                BigDecimal amount = BigDecimal.ZERO;
                BigDecimal quantity = BigDecimal.ZERO;
                String name = null;
                List<CouponCodeVo> couponCodeVoList= couponCodeService.selectExchangeVoList(order.getMemberId(),orderItem.getProductId());

                for (CouponCodeVo couponCodeVo:couponCodeVoList) {
                    amount = amount.add(orderItem.getSubTotal().divide(orderItem.getQuantity(),2,BigDecimal.ROUND_HALF_DOWN));
                    quantity = quantity.add(BigDecimal.ONE);
                    name = couponCodeVo.getName();
                    amount = amount.subtract(couponCodeVo.getAmount());
                    if (quantity.compareTo(orderItem.getQuantity())>=0) {
                        break;
                    }
                }

                if (amount.compareTo(BigDecimal.ZERO)>0) {

                    OrderPaymentVo vo = new OrderPaymentVo();
                    vo.setAmount(amount);
                    vo.setChk(true);
                    vo.setPaymentPluginId("couponCodePayPlugin");
                    vo.setBalance(amount);
                    vo.setPaymentPluginName(name);
                    vo.setQuantity(quantity);
                    Attach attach = new Attach();
                    attach.setQuantity(quantity);
                    attach.setProductId(orderItem.getProductId());
                    attach.setCode("9999");
                    attach.setQueue("queue.order.payment");
                    attach.setDescription(orderItem.getName());

                    vo.setAttach(JSON.toJSONString(attach));

                    list.add(vo);
                }
            }
        }

        //检查金币
        Member member = memberService.selectByPrimaryKey(order.getMemberId());
        if (member.getPoint().compareTo(0L)>0) {

            Long point = order.getAmountPayable().multiply(new BigDecimal(100)).longValue();
            if (point>member.calculateAvailablePoint()) {
                point = member.calculateAvailablePoint();
            }

            BigDecimal amount = new BigDecimal(point).multiply(new BigDecimal("0.01"));

            //计算本单能使用的金额
            if (amount.compareTo(BigDecimal.ZERO)>0) {
                OrderPaymentVo vo = new OrderPaymentVo();
                vo.setBalance(amount);
                vo.setAmount(BigDecimal.ZERO);
                vo.setChk(false);
                vo.setPaymentPluginId("pointPayPlugin");
                vo.setPaymentPluginName("金币");
                list.add(vo);
            }

        }

        List<Card> cards = cardService.getEffectiveCard(order.getMemberId());

        //检查我的专属卡会员卡
        Card maxCard = null;
        BigDecimal maxAmount = BigDecimal.ZERO;
        for (Card card:cards) {

            if (card.getCardType().equals(1)) {
                //计算本单能使用的金额
                BigDecimal amount = BigDecimal.ZERO;

                for (OrderItem orderItem:order.getItemList()) {
                    Product product = productService.findById(orderItem.getProductId());
                    if (checkCardTagExists(product.getTags(),card.getTags())) {
                        amount = amount.add(orderItem.getSubTotal());
                    }
                }
                if (amount.compareTo(card.getBalance())>0) {
                    amount = card.getBalance();
                }

                //能抵扣的最大金额
                if (amount.compareTo(BigDecimal.ZERO)>0) {
                    if (card.getTags().size()>0) {
                        if (amount.compareTo(maxAmount)>0) {
                            if (maxCard != null) {
                                //余额大的优先
                                if (maxCard.getBalance().compareTo(card.getBalance()) > 0) {
                                    continue;
                                }
                                //无过期时间的放后
                                if (maxCard.getEndDate() != null && card.getEndDate() == null) {
                                    continue;
                                }
                                if (maxCard.getEndDate() != null && card.getEndDate() != null) {
                                    if (maxCard.getEndDate().after(card.getEndDate())) {
                                        continue;
                                    }
                                }
                            }
                            maxCard = card;
                            maxAmount = amount;
                        }
                    } else {

                        OrderPaymentVo vo = new OrderPaymentVo();
                        vo.setAmount(BigDecimal.ZERO);
                        vo.setChk(false);
                        vo.setPaymentPluginId("cardPayPlugin");
                        vo.setEndDate(card.getEndDate());

                        vo.setBalance(amount);
                        String cardName = "福利卡";
                        if (card.getMemo()!=null) {
                            cardName = card.getMemo();
                        }
                        if (!"".equals(card.getCode()) && card.getCode().length()>4) {
                            vo.setPaymentPluginName(cardName + "（" + card.getCode().substring(card.getCode().length() - 4) + ")");
                        } else {
                            vo.setPaymentPluginName(cardName);
                        }
                        Attach attach = new Attach();
                        attach.setCardId(String.valueOf(card.getId()));
                        attach.setCode("9999");
                        attach.setQueue("queue.order.payment");
                        attach.setDescription(cardName);

                        vo.setAttach(JSON.toJSONString(attach));

                        list.add(vo);

                    }
                }
            }
        }

        if (maxCard!=null) {

            //计算本单能使用的金额
            BigDecimal amount = maxAmount;

            OrderPaymentVo vo = new OrderPaymentVo();
            vo.setAmount(BigDecimal.ZERO);
            vo.setChk(false);
            vo.setPaymentPluginId("cardPayPlugin");
            vo.setEndDate(maxCard.getEndDate());

            vo.setBalance(amount);
            String cardName = "福利卡";
            if (maxCard.getMemo()!=null) {
                cardName = maxCard.getMemo();
            }
            vo.setPaymentPluginName(cardName+"（" + maxCard.getCode().substring(maxCard.getCode().length() - 4) + ")");
            Attach attach = new Attach();
            attach.setCardId(String.valueOf(maxCard.getId()));
            attach.setCode("9999");
            attach.setQueue("queue.order.payment");
            attach.setDescription(cardName);

            vo.setAttach(JSON.toJSONString(attach));

            list.add(vo);

        }

        //检查我的通用卡会员卡
        for (Card card:cards) {

            if (card.getCardType().equals(0)) {
                //计算本单能使用的金额
                BigDecimal amount = order.getAmountPayable();
                if (amount.compareTo(card.getBalance())>0) {
                    amount = card.getBalance();
                }
                if (amount.compareTo(BigDecimal.ZERO)>0) {
                    OrderPaymentVo vo = new OrderPaymentVo();
                    vo.setAmount(BigDecimal.ZERO);
                    vo.setChk(false);
                    vo.setPaymentPluginId("cardPayPlugin");

                    vo.setPaymentPluginName("会员卡");
                    vo.setBalance(amount);

                    Attach attach = new Attach();
                    attach.setCardId(String.valueOf(card.getId()));
                    attach.setCode("9999");
                    attach.setQueue("queue.order.payment");
                    attach.setDescription("会员卡");

                    vo.setAttach(JSON.toJSONString(attach));

                    list.add(vo);
                }
            }

        }

        return list;
    }


    /**
     * 发货并出库
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Warehouse shippingAndAudit(Long id, Long shopId,Date orderDate,String weekTime, List<OrderItem> itemList,String sn) {
        Warehouse warehouse = shipping(id,shopId,orderDate,weekTime,itemList,sn);
        warehouseService.audit(warehouse.getId());
        return warehouse;
    }

    /**
     * 分批发货
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Warehouse shipping(Long id, Long shopId,Date orderDate,String weexTime, List<OrderItem> itemList,String sn) {

        //1、检查销售订单是否存在
        Order order = selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("未查找到订单");
        }

        //2、检查发货数量，并封装需要保存的orderItemList
        String errMsg = "";
        BigDecimal shippingQuantity = BigDecimal.ZERO;
        for (OrderItem paramItem : itemList) {

            OrderItem target = orderItemService.selectByPrimaryKey(paramItem.getId());
            if (target.getSubType().equals(1)) {
                //是套餐，需检查是否做套餐设置
                Map<String,Object> params = new HashMap<>();
                params.put("enterpriseId",order.getEnterpriseId());
                params.put("productId",target.getProductId());
                List<Bom> bomList = bomService.selectList(params);
                if (bomList.size()==0) {
                    throw new CustomException("请先设置套餐");
                }
            }

            //可发货数量
            BigDecimal canShippingQuantity = target.getQuantity().subtract(target.getReturnQuantity()).subtract(target.getShippedQuantity());
            if (canShippingQuantity.compareTo(BigDecimal.ZERO)<0) {
                canShippingQuantity = BigDecimal.ZERO;
            }
            //可发货数量与前端传过来的发货数量对比
            int result = canShippingQuantity.compareTo(paramItem.getShippedQuantity());
            if (result < 0){
                errMsg = "发货数量大于可发货数量";
                break;
            }

            if (paramItem.getShippedQuantity().compareTo(target.getQuantity())==0) {
                paramItem.setDiscount(target.getDiscount());
            } else {
                paramItem.setDiscount(target.getDiscount().multiply(paramItem.getShippedQuantity()).divide(target.getQuantity(),2,BigDecimal.ROUND_HALF_DOWN));
            }
            shippingQuantity = shippingQuantity.add(target.getShippedQuantity().add(paramItem.getShippedQuantity()));

        }

        if (StringUtils.isNotEmpty(errMsg)){
            throw new CustomException(errMsg);
        }

        //3、更新order的shippingStatus状态,检查状态是否发货完毕
        if (shippingQuantity.compareTo(order.getSubQuantity())>=0) {
            order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
        }

        order.setWeekTime(weexTime);
        order.setEstimateDate(enterpriseService.calcEstimateDate(order.getEnterpriseId(),new Date(),weexTime));
        int affectCount = orderMapper.updateByPrimaryKeySelective(order);
        Warehouse warehouse = null;

        if (affectCount > 0) {
            for (OrderItem target : itemList){
                if (target.getSubType().equals(0)) {
                    target.setQuantity(target.getShippedQuantity());
                }
            }

            //4、生成出库单
            order.setItemList(itemList);
            //使用前端手动选择的shopId出库
            order.setShopId(shopId);
            order.setOrderDate(orderDate);

            warehouse = this.insertWarehouse(order, WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_OUT.getId(), sn);

            OrderLog orderLog = new OrderLog();
            orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_SHIPPING.getId());
            orderLog.setContent("卖家已接单");
            orderLog.setCreateDate(new Date());
            orderLog.setOrderId(order.getId());
            orderLogService.insertUseGeneratedKeys(orderLog);

            try {
                Member member = memberService.selectByPrimaryKey(order.getMemberId());

                Map<String,Object> content = new HashMap<>();
                content.put("title","卖家已接单");
                content.put("itemList",order.getItemList());
                content.put("sn",order.getSn());
                content.put("id",order.getId());
                msgService.sendNotity(member,"msg-order","卖家已接单",JSON.toJSONString(content),null);

            } catch (Exception e) {
                log.error(e.getMessage());
            }
        } else {
            throw new CustomException("无效订单");
        }
        return warehouse;
    }


    //关闭时整单退款
    @Transactional(rollbackFor = Exception.class)
    public List<Refunds> refunds(Long id,String sn,String memo){

        //1、检查销售订单是否存在
        Order order = selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("未查找到订单");
        }
        //2、检查单据配送状态，非“未配送”和“已退货”，不可申请退款
        if (!order.getShippingStatus().equals(OrderShippingStatusEnum.SHIPPING_STATUS_UNSHIPPNG.getId())){
            throw new CustomException("已接单订单,不能退款!");
        }

        order.setItemList(orderItemService.getItemList(id));
        //3、查询订单的收款单,生成退款单
        Map<String,Object> param = new HashMap<>();
        param.put("orderId",order.getId());
        param.put("status",OrderPaymentStatusEnum.PAYMENT_STATUS_PAY.getId());
        param.put("sortField", "id");
        param.put("sortType","ASC");
        List<Payment> list = paymentService.selectList(param);

        List<Refunds> refundsList = new ArrayList<>();
        int w = 0;
        for (Payment payment : list){


            Refunds refunds = new Refunds();
            BeanUtils.copyProperties(payment, refunds);
            w ++ ;

            refunds.setSn(sn+"-"+String.valueOf(w));

            refunds.setMemo("退款-"+order.getTitle());
            refunds.setStatus(0);
            refunds.setPaymentId(payment.getId());
            refunds.setDeleted(false);

            Attach attachQueue = refunds.decodeAttach();
            attachQueue.setQueue("queue.order.refunds");

            refunds.setAttach(JSON.toJSONString(attachQueue));

            refundsService.insertUseGeneratedKeys(refunds);

            payment.setRefund(payment.getAmount());
            paymentService.updateByPrimaryKeySelective(payment);

            if ("waterTicketPayPlugin".equals(payment.getPaymentPluginId())) {
                virtualStockService.refunds(refunds);
            } else
            if ("couponCodePayPlugin".equals(payment.getPaymentPluginId())) {
                couponCodeOrderService.refunds(refunds);
            } else {
                refundsService.execRefunds(refunds);

            }

            if (!refunds.getStatus().equals(Refunds.STATUS_REFUNDED) && !refunds.getStatus().equals(Refunds.STATUS_SUCCESS)) {
                refundsList.add(refunds);
            }

        }

        order.setModifyDate(new Date());
        orderMapper.updateByPrimaryKeySelective(order);

        return refundsList;
    }

    private void addPromotion(Order order,Promotion promotion,BigDecimal quantity) {
        OrderPromotion orderPromotion = new OrderPromotion();
        orderPromotion.setCreateDate(new Date());
        orderPromotion.setOrderId(order.getId());
        orderPromotion.setPromotionId(promotion.getId());
        orderPromotion.setTitle(promotion.getTitle());
        orderPromotion.setType(promotion.getType());
        orderPromotion.setQuantity(quantity);
        orderPromotion.setPromotion(promotion);
        List<OrderPromotion> promotionList = order.getPromotions();
        promotionList.add(orderPromotion);
    }


    /**
     * 分批退货单
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Warehouse returnsAndAudit(Long id, Long shopId, Date orderDate, List<OrderItem> itemList,String sn) {
        Warehouse warehouse = returns(id,shopId,orderDate,itemList,sn);
        warehouseService.audit(warehouse.getId());
        return warehouse;

    }

        /**
         * 分批退货单
         * @return
         */
    @Transactional(rollbackFor = Exception.class)
    public Warehouse returns(Long id, Long shopId, Date orderDate, List<OrderItem> itemList,String sn) {
        //1、检查销售订单是否存在
        Order order = selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("未查找到订单");
        }

        //2、检查退货数量，并封装需要保存的orderItemList
        String errMsg = "";
        BigDecimal returnQuantity = BigDecimal.ZERO;
        BigDecimal shippingQuantity = BigDecimal.ZERO;
        for (OrderItem paramItem : itemList){
            OrderItem target = orderItemService.selectByPrimaryKey(paramItem.getId());
            //可退货数量
            BigDecimal canReturnQuantity = target.getQuantity().subtract(target.getReturnQuantity());
            if (canReturnQuantity.compareTo(BigDecimal.ZERO)<0) {
                canReturnQuantity = BigDecimal.ZERO;
            }
            //可退货数量与前端传过来的退货数量对比
            int result = canReturnQuantity.compareTo(paramItem.getReturnQuantity());
            if (result < 0){
                errMsg = "退货数量大于可退货数量";
                break;
            }
            if (paramItem.getShippedQuantity().compareTo(target.getQuantity())==0) {
                paramItem.setDiscount(target.getDiscount());
            } else {
                paramItem.setDiscount(target.getDiscount().multiply(paramItem.getReturnQuantity()).divide(target.getQuantity(), 2, BigDecimal.ROUND_HALF_DOWN));
            }
            shippingQuantity = shippingQuantity.add(target.getShippedQuantity());
            returnQuantity = returnQuantity.add(target.getReturnQuantity().add(paramItem.getReturnQuantity()));

        }
        if (StringUtils.isNotEmpty(errMsg)){
            throw new CustomException(errMsg);
        }

        //3、更新order的shippingStatus状态
        if (shippingQuantity.compareTo(returnQuantity)<=0) {
            order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_REFUND_SHIPPING.getId());
        }

        int affectCount = updateByPrimaryKeySelective(order);
        Warehouse warehouse = null;
        if (affectCount > 0) {

            for (OrderItem target : itemList){
                target.setQuantity(target.getReturnQuantity());
            }

            //4、生成入库单
            order.setItemList(itemList);
            //使用前端手动选择的shopId出库
            order.setShopId(shopId);
            order.setOrderDate(orderDate);
            warehouse = this.insertWarehouse(order, WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId(),sn);

            OrderLog orderLog = new OrderLog();
            orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_RETURN.getId());
            orderLog.setContent("订单已退货");
            orderLog.setCreateDate(new Date());
            orderLog.setOrderId(order.getId());
            orderLogService.insertUseGeneratedKeys(orderLog);

            try {
                Member member = memberService.selectByPrimaryKey(order.getMemberId());

                Map<String,Object> content = new HashMap<>();
                content.put("title","您的订单已退货");
                content.put("itemList",order.getItemList());
                content.put("sn",order.getSn());
                content.put("id",order.getId());
                msgService.sendNotity(member,"msg-order","您的订单已退货",JSON.toJSONString(content),null);

            } catch (Exception e) {
                log.error(e.getMessage());
            }


        } else {
            throw new CustomException("无效订单");
        }
        return warehouse;
    }

    /**
     * 取消
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public List<Refunds> cancel(Long id,String sn) {

        //1、检查销售订单是否存在
        Order order = selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("未查找到订单");
        }

        if (order.getOrderStatus().compareTo(OrderStatusEnum.ORDER_STATUS_CANCLE.getId())==0) {
            throw new CustomException("订单已关闭");
        }

        order.setItemList(orderItemService.getItemList(id));

        //扣减商品库存
        for (OrderItem sortItem:order.sortItemList()) {
            int r = productService.addStock(sortItem.getProductId(),sortItem.getQuantity());
        }

        Map<String,Object> params = new HashMap<>();
        params.put("orderId",order.getId());
        params.put("enterpriseId",order.getEnterpriseId());

        //未收款,撤消
        List<Payment> paymentList = paymentService.selectList(params);
        for (Payment payment:paymentList) {
            if (payment.getStatus().equals(0)) {
                Receivable receivable = receivableService.selectByPrimaryKey(payment.getReceivableId());
                if (receivable!=null) {
                    receivable.setAmountPaid(receivable.getAmountPaid().subtract(payment.getAmount()));
                    if (receivable.getAmountPaid().compareTo(BigDecimal.ZERO) > 0) {
                        receivable.setStatus(1);
                    } else {
                        receivable.setStatus(0);
                    }
                    if (receivable.getStatus().equals(0)) {
                        receivableService.delete(receivable);
                    } else {
                        receivableService.updateByPrimaryKeySelective(receivable);
                    }
                    paymentService.delete(payment);
                }
            }
        }


        //已收款,撤消

        List<Receivable> receivableList = receivableService.selectList(params);
        for (Receivable receivable:receivableList) {
            if (receivable.getAmountPaid().compareTo(BigDecimal.ZERO)>0) {
                throw new CustomException("已收款不能关闭");
            }
            receivableService.delete(receivable);

        }


        //有送货单,撤消

        List<Askfor> askforList = askforService.selectList(params);
        for (Askfor askfor:askforList) {
            if (askfor.getStatus().equals(2) || askfor.getStatus().equals(3) || askfor.getStatus().equals(4)) {
                throw new CustomException("退款中不能关闭");
            }
            if (!askfor.getStatus().equals(5)) {
                askforService.cancel(askfor.getId());
            }
        }

        //有出库单，撤消

        List<Warehouse> warehouseList = warehouseService.selectList(params);
        for (Warehouse warehouse:warehouseList) {
            if (warehouse.getStatus().equals(2)) {
                throw new CustomException("已出库不能关闭");
            }
            if (!warehouse.getStatus().equals(3)) {
                warehouseService.cancel(warehouse.getId());
            }
        }

        //有已收款，发起退款
        List<Refunds> refundsList = refunds(id,sn,"关闭订单");

        order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_CANCLE.getId());

        super.updateByPrimaryKeySelective(order);

        order.setPromotions(orderPromotionService.getPromotions(id));

        for (OrderPromotion promotion:order.getPromotions()) {
            //单品活动,回退库存
            if (promotion.getType().equals(7) || promotion.getType().equals(8) || promotion.getType().equals(9) || promotion.getType().equals(10)) {
                promotionService.addStock(promotion.getPromotionId(),promotion.getQuantity().setScale(0,BigDecimal.ROUND_UP).intValue());
            }
        }

        if (order.getCouponCodeId()!=null) {
            CouponCode couponCode = couponCodeService.selectByPrimaryKey(order.getCouponCodeId());
            if (couponCode!=null) {
                couponCode.setIsUsed(false);
                couponCode.setUsedDate(new Date());
                couponCodeService.updateByPrimaryKeySelective(couponCode);
            }
        }


        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_CANCEL.getId());
        orderLog.setContent("订单已关闭");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(order.getId());
        orderLogService.insertUseGeneratedKeys(orderLog);

        try {
            Member member = memberService.selectByPrimaryKey(order.getMemberId());

            member.setAmount(member.getAmount().subtract(order.getAmountPayable()));
            memberService.updateByPrimaryKeySelective(member);

            Map<String,Object> content = new HashMap<>();
            content.put("title","您的订单已关闭");
            content.put("itemList",order.getItemList());
            content.put("sn",order.getSn());
            content.put("id",order.getId());
            msgService.sendNotity(member,"msg-order","您的订单已关闭",JSON.toJSONString(content),null);

        } catch (Exception e) {
            log.error(e.getMessage());
        }


        return refundsList;
    }


    /**
     * 确认收货
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int received(Long id,Boolean robot) {

        //1、检查销售订单是否存在
        Order order = selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("未查找到订单");
        }
        order.setItemList(orderItemService.getItemList(id));

        //检查是否有未完成退款

        if (order.getShippingStatus().equals(OrderShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId())) {

            //检查是否收货完毕

            BigDecimal quantity = BigDecimal.ZERO;
            BigDecimal shippingQuantity = BigDecimal.ZERO;
            BigDecimal returnedQuantity = BigDecimal.ZERO;
            for (OrderItem orderItem:order.getItemList()) {
                quantity = quantity.add(orderItem.getQuantity());
                shippingQuantity = shippingQuantity.add(orderItem.getShippedQuantity());
                returnedQuantity = returnedQuantity.add(orderItem.getReturnQuantity());
            }

            Map<String,Object> params = new HashMap<>();
            params.put("orderId",id);
            List<Askfor> askforList = askforService.selectList(params);
            for (Askfor askfor:askforList) {
                if (!askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_COMPLETE.getId()) && !askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_CANCLEED.getId())) {
                    throw new CustomException("退款未完成");
                }
            }

            List<Shipping> shippingList = shippingService.selectList(params);
            for (Shipping rn:shippingList) {
                if (rn.getShippingStatus().equals(0) || rn.getShippingStatus().equals(1) || rn.getShippingStatus().equals(2)) {
                    throw new CustomException("发货未完成");
                }
            }

            if (robot) {

                //代表没有发货完成
                if (quantity.subtract(shippingQuantity).subtract(returnedQuantity).compareTo(BigDecimal.ZERO)>0) {
                   return 0;
                }

                for (Shipping shipping:shippingList) {
                    if (!shipping.getShippingStatus().equals(ShippingStatusEnum.SHIPPING_STATUS_CANCELED.getId())) {
                        //存在未发货订单
                        if (shipping.getDeliveryDate() == null) {
                            return 0;
                        }
                        //存在没有到7天不自动签收
                        if (shipping.getDeliveryDate().after(DateUtils.addDays(new Date(), -7))) {
                            return 0;
                        }
                    }
                }

            }


            order.setOrderStatus(OrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
            orderMapper.updateByPrimaryKeySelective(order);

            //对金币解冻
            if (order.getPoint()>0L) {
                //消费返积分
                matchPointService.addMatchPoint(order.getMemberId(),order.getPoint(),"消费返积分",0,order.getId());
            }

            if (order.getRebate1().compareTo(BigDecimal.ZERO)>0) {
                pointService.decFreezePoint(order.getPromoterId1(),order.getRebate1().longValue());
            }
            if (order.getRebate2().compareTo(BigDecimal.ZERO)>0) {
                pointService.decFreezePoint(order.getPromoterId2(),order.getRebate2().longValue());
            }
            if (order.getAgent1().compareTo(BigDecimal.ZERO)>0) {
                pointService.decFreezePoint(order.getAgentId1(),order.getAgent1().longValue());
            }


            List<Shipping> completeList = shippingService.selectList(params);
            for (Shipping cl:completeList) {
                //if (cl.getShippingStatus().equals(3)) {
                    shippingService.complete(cl.getId(),null);
                //}
            }


            addFoundation(order.getId());

            addAchieve(order.getId());

            //处理单品的买赠活动
            createPromotion(order);

            OrderLog orderLog = new OrderLog();
            orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_COMPLETE.getId());
            if (robot==true) {
                orderLog.setContent("过期系统签收");
            } else {
                orderLog.setContent("用户已签收");

            }
            orderLog.setCreateDate(new Date());
            orderLog.setOrderId(order.getId());
            orderLogService.insertUseGeneratedKeys(orderLog);

            try {
                Member member = memberService.selectByPrimaryKey(order.getMemberId());

                Map<String,Object> content = new HashMap<>();
                content.put("title","您的订单已签收");
                content.put("itemList",order.getItemList());
                content.put("sn",order.getSn());
                content.put("id",order.getId());
                msgService.sendNotity(member,"msg-order","您的订单已签收",JSON.toJSONString(content),null);

            } catch (Exception e) {
                log.error(e.getMessage());
            }

        } else {
            throw new CustomException("订单不在待收货");
        }
        return 1;

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByIds(Object[] ids) {
        int rw = 0;
        for (Object id:ids) {
            Order order = selectByPrimaryKey(id);
            order.setDeleted(true);
            rw = rw + orderMapper.updateByPrimaryKeySelective(order);
        }
        return rw;
    }

    @Transactional(rollbackFor = Exception.class)
    public int update(Order order) {

        Order orgOrder = orderMapper.selectByPrimaryKey(order.getId());
        if (orgOrder.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_UNCONFIRM.getId())) {
            throw new CustomException("已确认订单不能修改");
        }

        //店铺优惠+抹零，按交易金额分滩到每个商品
        log.info("按交易金额分滩到每个商品");
        BigDecimal discount = order.getDiscount().subtract(order.getOffsetAmount());
        if (discount.compareTo(BigDecimal.ZERO)>0) {
            BigDecimal balance = discount;
            BigDecimal totalAmount = order.getSubPrice();
            //开始分摊活动费用
            for (OrderItem orderItem : order.getItemList()) {
                if (orderItem.getIsGift() == false) {
                    BigDecimal d = orderItem.getAmount().
                            multiply(discount).
                            divide(totalAmount, 2, BigDecimal.ROUND_DOWN);
                    orderItem.setIsGift(false);
                    orderItem.setDiscount(d);
                    balance = balance.subtract(d);
                }
            }
            //结余没分完的，分到第一个商品中
            OrderItem orderItem = order.getItemList().get(0);
            orderItem.setDiscount(orderItem.getDiscount().add(balance));
        }

        order.setAmountPayable(order.calculateAmountPayable());
        order.setAmountPaid(BigDecimal.ZERO);

        //只用于修改抹零及收货地址信息
        int affectCount = orderMapper.updateByPrimaryKeySelective(order);

        return affectCount;

    }

    public Integer checkBomType(Order order) {
        //处理单次套餐里的水票
        for (OrderItem orderItem : order.getItemList()) {
            if (orderItem.getSubType().equals(1)) {
                //套餐时，生成配送计划
                Bom bom = null;
                Map<String, Object> params = new HashMap<>();
                params.put("enterpriseId", order.getEnterpriseId());
                params.put("productId", orderItem.getProductId());
                List<Bom> bomList = bomService.selectList(params);
                if (bomList.size() > 0) {
                    bom = bomList.get(0);
                }

                if (bom == null) {
                    throw new CustomException("请设置套餐");
                }

                if (bom.getQuantity() > 1) {
                    return 1;
                }

            }
        }
        return 0;
    }

    public Integer calculatePoint(Order order) {
        Integer point = 0;
        for (OrderItem orderItem:order.getItemList()) {
            Product product = productService.selectByPrimaryKey(orderItem.getProductId());
            if (product.getType().equals(2)) {
                point = product.getPoint();
            }
        }

        return point;
    }

    /**
     * 生成出入库
     * @param order
     */
    @Transactional(rollbackFor = Exception.class)
    public Warehouse insertWarehouse(Order order, Integer warehouseType,String sn) {

        Warehouse warehouse = new Warehouse();
        warehouse.setSn(sn);
        warehouse.setAddress(order.getAddress());
        warehouse.setAreaId(order.getAreaId());
        warehouse.setAreaName(order.getAreaName());
        warehouse.setConsignee(order.getConsignee());
        warehouse.setPhone(order.getPhone());
        warehouse.setMemo(order.getMemo());
        warehouse.setStatus(0);
        warehouse.setOrderMethod(order.getOrderMethod());
        warehouse.setShippingMethod(order.getShippingMethod());
        warehouse.setWarehouseType(warehouseType);
        warehouse.setSubPrice(order.getSubPrice());
        warehouse.setSubQuantity(order.getSubQuantity());
        warehouse.setTaxType(order.getTaxType());
        warehouse.setMemberId(order.getMemberId());
        warehouse.setOrderId(order.getId());
        warehouse.setOrderSn(order.getSn());
        warehouse.setEnterpriseId(order.getEnterpriseId());
        warehouse.setShopId(order.getShopId());
        warehouse.setDeleted(false);
        warehouse.setOfficeId(order.getOfficeId());
        //warehouse.setOperatorId(sysUser.getId());
        warehouse.setSPrint(0);
        warehouse.setSupplierId(order.getMemberId());
        warehouse.setOrderDate(DateUtils.truncate(order.getOrderDate(),Calendar.DATE));
        warehouse.setCompanyId(order.getCompanyId());

        //明细表数据
        List<WarehouseItem> itemsList = new ArrayList<>();
        for (OrderItem orderItem : order.getItemList()){
            if (orderItem.getQuantity().compareTo(BigDecimal.ZERO) > 0) {
                WarehouseItem warehouseItem = new WarehouseItem();
                warehouseItem.setSubType(orderItem.getSubType());
                warehouseItem.setCost(orderItem.getCost());
                warehouseItem.setName(orderItem.getName());
                warehouseItem.setPrice(orderItem.getPrice());
                warehouseItem.setQuantity(orderItem.getQuantity());
                warehouseItem.setSn(orderItem.getSn());
                warehouseItem.setUnit(orderItem.getUnit());
                warehouseItem.setSpec(orderItem.getSpec());
                warehouseItem.setThumbnail(orderItem.getThumbnail());
                warehouseItem.setProductId(orderItem.getProductId());
                warehouseItem.setWarehouseId(warehouse.getId());
                warehouseItem.setDiscount(orderItem.getDiscount());
                //冗余存储
                warehouseItem.setShopId(warehouse.getShopId());
                warehouseItem.setEnterpriseId(warehouse.getEnterpriseId());
                warehouseItem.setTax(BigDecimal.ZERO);
                itemsList.add(warehouseItem);
            }

            if (orderItem.getSubType().equals(1)) {
                //套餐时，生成配送计划
                Bom bom = null;
                Map<String,Object> params = new HashMap<>();
                params.put("enterpriseId",order.getEnterpriseId());
                params.put("productId",orderItem.getProductId());
                List<Bom> bomList = bomService.selectList(params);
                if (bomList.size()>0) {
                    bom = bomList.get(0);
                }

                if (bom==null) {
                    throw new CustomException("请设置套餐");
                }

                if (bom.getQuantity()>1) {
                    continue;
                }

                List<BomItem> bomItemList = bomItemService.getItemList(bom.getId());
                for (BomItem bomItem:bomItemList) {
                    Product product = productService.selectByPrimaryKey(bomItem.getProductId());

                    WarehouseItem warehouseItem = new WarehouseItem();
                    warehouseItem.setSubType(product.getSubType());
                    warehouseItem.setCost(product.getCost());
                    warehouseItem.setName(product.getName());
                    warehouseItem.setPrice(BigDecimal.ZERO);
                    warehouseItem.setQuantity(bomItem.getConvRate().multiply(orderItem.getQuantity()));
                    warehouseItem.setSn(product.getSn());
                    warehouseItem.setUnit(product.getUnit());
                    warehouseItem.setSpec(product.getSpec());
                    warehouseItem.setThumbnail(product.getThumbnail());
                    warehouseItem.setProductId(product.getId());
                    warehouseItem.setWarehouseId(warehouse.getId());
                    warehouseItem.setDiscount(BigDecimal.ZERO);
                    //冗余存储
                    warehouseItem.setShopId(warehouse.getShopId());
                    warehouseItem.setEnterpriseId(warehouse.getEnterpriseId());
                    warehouseItem.setTax(BigDecimal.ZERO);
                    itemsList.add(warehouseItem);
                }


                OrderItem wOrderItem = orderItemService.selectByPrimaryKey(orderItem.getId());
                if (wOrderItem!=null) {
                    //本商品剩余可发货数量
                    BigDecimal canShippingQty = wOrderItem.getQuantity().subtract(wOrderItem.getShippedQuantity());
                    BigDecimal shippingQuantity = BigDecimal.ZERO;
                    //当可发货数量大于本次发货数量，用本次发货数量
                    if (canShippingQty.compareTo(orderItem.getQuantity()) >= 0) {
                        shippingQuantity = orderItem.getQuantity();
                        wOrderItem.setShippedQuantity(shippingQuantity.add(wOrderItem.getShippedQuantity()));
                        orderItemService.updateByPrimaryKeySelective(wOrderItem);
                    } else {
                        //当可发货数量小于本次发货数量，用商品可发货数量，当前商品剩余未发货数量继续循环
                        shippingQuantity = canShippingQty;
                        wOrderItem.setShippedQuantity(shippingQuantity.add(wOrderItem.getShippedQuantity()));
                        orderItemService.updateByPrimaryKeySelective(wOrderItem);
                    }
                }


            }
        }

        warehouse.setItemList(itemsList);

        warehouse.setSubPrice(warehouse.calculateSubPrice());
        warehouse.setSubQuantity(warehouse.calculateSubQuantity());

        if (itemsList.size()>0) {

            warehouseService.insertUseGeneratedKeys(warehouse);
            //自动确认
            warehouseService.confirm(warehouse.getId());
        }

        return warehouse;

    }

    private void initOrder(Order order){
        if (order.getIsFirst()==null) {
            order.setIsFirst(false);
        }
        if (order.getIsDistribution()==null) {
            order.setIsDistribution(false);
        }
        //若空，默认0线上结算
        if (null == order.getAmountPaid()){
            order.setAmountPaid(BigDecimal.ZERO);
        }
        if (null == order.getAmountPayable()){
            order.setAmountPayable(BigDecimal.ZERO);
        }
        if (null == order.getFee()){
            order.setFee(BigDecimal.ZERO);
        }
        if (null == order.getFreight()){
            order.setFreight(BigDecimal.ZERO);
        }
        if (null == order.getLevelFreight()){
            order.setLevelFreight(BigDecimal.ZERO);
        }
        if (null == order.getOffsetAmount()){
            order.setOffsetAmount(BigDecimal.ZERO);
        }
        if (null == order.getPoint()){
            order.setPoint(0L);
        }
        if (null == order.getDiscount()){
            order.setDiscount(BigDecimal.ZERO);
        }
        if (null == order.getSubPrice()){
            order.setSubPrice(BigDecimal.ZERO);
        }
        if (null == order.getSubQuantity()){
            order.setSubQuantity(BigDecimal.ZERO);
        }
        if (null == order.getCouponCodeId()){
            order.setCouponCodeId(0L);
        }
        if (null == order.getMemberId()){
            order.setMemberId(0L);
        }
        if (null == order.getShippingMethod()){
            order.setShippingMethod(0);
        }
        if (null == order.getLat()){
            order.setLat(0d);
        }
        if (null == order.getLng()){
            order.setLng(0d);
        }

        if (null == order.getTax()){
            order.setTax(new BigDecimal(17));
        }
        if (null == order.getShopId()){
            order.setShopId(null);
        }

        if (null == order.getOrderMethod()){
            order.setOrderMethod(0);
        }

        if (null == order.getRebate1()){
            order.setRebate1(BigDecimal.ZERO);
        }
        if (null == order.getRebate2()){
            order.setRebate2(BigDecimal.ZERO);
        }
        if (null == order.getAgent1()){
            order.setAgent1(BigDecimal.ZERO);
        }

        if (null == order.getTaxType()){
            order.setTaxType(0);
        }
        if (null == order.getInvoiced()){
            order.setInvoiced(false);
        }
        if (null == order.getOrderStatus()){
            order.setOrderStatus(0);
        }
        if (null == order.getPaymentStatus()){
            order.setPaymentStatus(0);
        }
        if (null == order.getShippingStatus()){
            order.setShippingStatus(0);
        }
        if (null == order.getOrderDate()){
            order.setOrderDate(DateUtils.truncate(new Date(),Calendar.DATE));
        } else {
            order.setOrderDate(DateUtils.truncate(order.getOrderDate(),Calendar.DATE));
        }
    }

    private void initOrderItem(OrderItem orderItem){

        Product product = productService.selectByPrimaryKey(orderItem.getProductId());
        orderItem.setSn(product.getSn());
        orderItem.setCost(product.getCost());
        orderItem.setName(product.getName());
        if (product.getSpec1()==null) {
            product.setSpec1("");
        }
        if (product.getSpec2()==null) {
            product.setSpec2("");
        }
        orderItem.setThumbnail(product.getThumbnail());
        orderItem.setSpec(product.getSpec1()+product.getSpec2());
        orderItem.setUnit(product.getUnit());
        orderItem.setWeight(product.getWeight());
        if (orderItem.getWeight()==null) {
            orderItem.setWeight(BigDecimal.ZERO);
        }
        if (null == orderItem.getIsGift()){
            orderItem.setIsGift(false);
        }
        if (null == orderItem.getReturnQuantity()){
            orderItem.setReturnQuantity(BigDecimal.ZERO);
        }
        if (null == orderItem.getShippedQuantity()){
            orderItem.setShippedQuantity(BigDecimal.ZERO);
        }

        if (null == orderItem.getDiscount()){
            orderItem.setDiscount(BigDecimal.ZERO);
        }
        if (null == orderItem.getCouponCodeQuantity()){
            orderItem.setCouponCodeQuantity(0L);
        }

    }

    public int updateOne(Order order){
        order.setMemo("test");
        orderMapper.updateByPrimaryKeySelective(order);

        order.setMemo(null);
        updateTwo(order);
        return 1;
    }

    @Transactional
    public int updateTwo(Order order){
        order.setTrackingNo("1");
        orderMapper.updateByPrimaryKeySelective(order);
        int num = Integer.valueOf("a");
        return 1;
    }
}
